playbook_ui 11.15.0 → 11.16.0.pre.alpha.paginationrails1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/app/pb_kits/playbook/_playbook.scss +2 -0
  3. data/app/pb_kits/playbook/data/menu.yml +1 -0
  4. data/app/pb_kits/playbook/index.js +2 -2
  5. data/app/pb_kits/playbook/pb_bar_graph/_bar_graph.tsx +145 -0
  6. data/app/pb_kits/playbook/pb_circle_chart/ChartsTypes.ts +2 -0
  7. data/app/pb_kits/playbook/pb_circle_chart/_circle_chart.tsx +207 -0
  8. data/app/pb_kits/playbook/pb_circle_chart/circle_chart.html.erb +9 -21
  9. data/app/pb_kits/playbook/pb_circle_chart/circle_chart.rb +7 -47
  10. data/app/pb_kits/playbook/pb_dashboard/pbChartsColorsHelper.ts +16 -0
  11. data/app/pb_kits/playbook/pb_dashboard/{pbChartsDarkTheme.js → pbChartsDarkTheme.ts} +6 -21
  12. data/app/pb_kits/playbook/pb_dashboard/{pbChartsLightTheme.js → pbChartsLightTheme.ts} +6 -21
  13. data/app/pb_kits/playbook/pb_dashboard/themeTypes.ts +16 -0
  14. data/app/pb_kits/playbook/pb_gauge/_gauge.scss +4 -0
  15. data/app/pb_kits/playbook/pb_gauge/_gauge.tsx +202 -0
  16. data/app/pb_kits/playbook/pb_gauge/docs/_gauge_complex.html.erb +1 -1
  17. data/app/pb_kits/playbook/pb_gauge/docs/_gauge_complex.jsx +8 -8
  18. data/app/pb_kits/playbook/pb_gauge/gauge.html.erb +1 -11
  19. data/app/pb_kits/playbook/pb_gauge/gauge.rb +3 -8
  20. data/app/pb_kits/playbook/pb_line_graph/_line_graph.tsx +148 -0
  21. data/app/pb_kits/playbook/pb_pagination/_pagination.scss +68 -0
  22. data/app/pb_kits/playbook/pb_pagination/_pagination.tsx +41 -0
  23. data/app/pb_kits/playbook/pb_pagination/docs/_pagination_default.html.erb +28 -0
  24. data/app/pb_kits/playbook/pb_pagination/docs/_pagination_default.jsx +12 -0
  25. data/app/pb_kits/playbook/pb_pagination/docs/example.yml +9 -0
  26. data/app/pb_kits/playbook/pb_pagination/docs/index.js +1 -0
  27. data/app/pb_kits/playbook/pb_pagination/pagination.html.erb +7 -0
  28. data/app/pb_kits/playbook/pb_pagination/pagination.rb +18 -0
  29. data/app/pb_kits/playbook/pb_pagination/pagination.test.jsx +17 -0
  30. data/app/pb_kits/playbook/pb_treemap_chart/_treemap_chart.tsx +111 -0
  31. data/app/pb_kits/playbook/pb_treemap_chart/docs/_treemap_chart_tooltip.jsx +1 -1
  32. data/app/pb_kits/playbook/playbook-doc.js +2 -0
  33. data/app/pb_kits/playbook/playbook-rails-react-bindings.js +4 -0
  34. data/app/pb_kits/playbook/playbook-rails.js +0 -4
  35. data/lib/playbook/kit_base.rb +2 -0
  36. data/lib/playbook/pagination_renderer.rb +41 -0
  37. data/lib/playbook/version.rb +2 -2
  38. data/lib/playbook.rb +1 -0
  39. metadata +38 -12
  40. data/app/pb_kits/playbook/pb_bar_graph/_bar_graph.jsx +0 -111
  41. data/app/pb_kits/playbook/pb_circle_chart/_circle_chart.jsx +0 -151
  42. data/app/pb_kits/playbook/pb_gauge/_gauge.jsx +0 -112
  43. data/app/pb_kits/playbook/pb_line_graph/_line_graph.jsx +0 -113
  44. data/app/pb_kits/playbook/pb_treemap_chart/_treemap_chart.jsx +0 -79
  45. data/app/pb_kits/playbook/plugins/pb_chart.js +0 -322
@@ -0,0 +1,202 @@
1
+ import React, { useState, useEffect } from "react";
2
+ import classnames from "classnames";
3
+ import HighchartsReact from "highcharts-react-official";
4
+ import Highcharts from "highcharts";
5
+ import { highchartsTheme } from "../pb_dashboard/pbChartsLightTheme";
6
+ import { highchartsDarkTheme } from "../pb_dashboard/pbChartsDarkTheme";
7
+ import mapColors from "../pb_dashboard/pbChartsColorsHelper";
8
+ import highchartsMore from "highcharts/highcharts-more";
9
+ import solidGauge from "highcharts/modules/solid-gauge";
10
+ import defaultColors from "../tokens/exports/_colors.scss";
11
+ import typography from "../tokens/exports/_typography.scss";
12
+
13
+ import { buildAriaProps, buildCss, buildDataProps } from "../utilities/props";
14
+ import { globalProps } from "../utilities/globalProps";
15
+
16
+ type GaugeProps = {
17
+ aria: { [key: string]: string };
18
+ className?: string;
19
+ chartData?: { name: string; value: number[] | number }[];
20
+ dark?: Boolean;
21
+ data?: { [key: string]: string };
22
+ disableAnimation?: boolean;
23
+ fullCircle?: boolean;
24
+ height?: string;
25
+ id?: string;
26
+ max?: number;
27
+ min?: number;
28
+ prefix?: string;
29
+ showLabels?: boolean;
30
+ style?: string;
31
+ suffix?: string;
32
+ title?: string;
33
+ tooltipHtml?: string;
34
+ colors: string[];
35
+ minorTickInterval: any;
36
+ circumference: number[];
37
+ };
38
+
39
+ const Gauge = ({
40
+ aria = {},
41
+ className,
42
+ chartData,
43
+ dark = false,
44
+ data = {},
45
+ disableAnimation = false,
46
+ fullCircle = false,
47
+ height = null,
48
+ id,
49
+ max = 100,
50
+ min = 0,
51
+ prefix = "",
52
+ showLabels = false,
53
+ style = "solidgauge",
54
+ suffix = "",
55
+ title = "",
56
+ tooltipHtml = '<span style="font-weight: bold; color:{point.color};">●</span>{point.name}: ' +
57
+ "<b>{point.y}</b>",
58
+ colors = [],
59
+ minorTickInterval = null,
60
+ circumference = fullCircle ? [0, 360] : [-100, 100],
61
+ ...props
62
+ }: GaugeProps) => {
63
+ const ariaProps = buildAriaProps(aria);
64
+ const dataProps = buildDataProps(data);
65
+ highchartsMore(Highcharts);
66
+ solidGauge(Highcharts);
67
+ const setupTheme = () => {
68
+ dark
69
+ ? Highcharts.setOptions(highchartsDarkTheme)
70
+ : Highcharts.setOptions(highchartsTheme);
71
+ };
72
+ setupTheme();
73
+
74
+ //set tooltip directly to prevent being overriden by Highcharts defaults
75
+ Highcharts.setOptions({
76
+ tooltip: {
77
+ pointFormat: tooltipHtml,
78
+ followPointer: true,
79
+ },
80
+ });
81
+
82
+ const css = buildCss({
83
+ pb_gauge_kit: true,
84
+ });
85
+
86
+ const [options, setOptions] = useState({});
87
+
88
+ useEffect(() => {
89
+ const formattedChartData = chartData.map((obj: any) => {
90
+ obj.y = obj.value;
91
+ delete obj.value;
92
+ return obj;
93
+ });
94
+
95
+ const staticOptions = {
96
+ chart: {
97
+ events: {
98
+ load() {
99
+ setTimeout(this.reflow.bind(this), 0);
100
+ },
101
+ },
102
+ type: style,
103
+ height: height,
104
+ },
105
+ title: {
106
+ text: title,
107
+ },
108
+ yAxis: {
109
+ min: min,
110
+ max: max,
111
+ lineWidth: 0,
112
+ tickWidth: 0,
113
+ minorTickInterval: minorTickInterval,
114
+ tickAmount: 2,
115
+ tickPositions: [min, max],
116
+ labels: {
117
+ y: 26,
118
+ enabled: showLabels,
119
+ },
120
+ },
121
+ credits: false,
122
+ series: [
123
+ {
124
+ data: formattedChartData,
125
+ },
126
+ ],
127
+ pane: {
128
+ center: ["50%", "50%"],
129
+ size: "90%",
130
+ startAngle: circumference[0],
131
+ endAngle: circumference[1],
132
+ background: {
133
+ borderWidth: 20,
134
+ innerRadius: "90%",
135
+ outerRadius: "90%",
136
+ shape: "arc",
137
+ className: "gauge-pane",
138
+ },
139
+ },
140
+ colors:
141
+ colors !== undefined && colors.length > 0
142
+ ? mapColors(colors)
143
+ : highchartsTheme.colors,
144
+ plotOptions: {
145
+ series: {
146
+ animation: !disableAnimation,
147
+ },
148
+ solidgauge: {
149
+ borderColor:
150
+ colors !== undefined && colors.length === 1
151
+ ? mapColors(colors).join()
152
+ : highchartsTheme.colors[0],
153
+ borderWidth: 20,
154
+ radius: 90,
155
+ innerRadius: "90%",
156
+ dataLabels: {
157
+ borderWidth: 0,
158
+ color: defaultColors.text_lt_default,
159
+ enabled: true,
160
+ format:
161
+ `<span class="prefix">${prefix}</span>` +
162
+ '<span class="fix">{y:,f}</span>' +
163
+ `<span class="suffix">${suffix}</span>`,
164
+ style: {
165
+ fontFamily: typography.font_family_base,
166
+ fontWeight: typography.regular,
167
+ fontSize: typography.heading_2,
168
+ },
169
+ y: -26,
170
+ },
171
+ },
172
+ },
173
+ };
174
+
175
+ setOptions({ ...staticOptions });
176
+
177
+ if (document.querySelector(".prefix")) {
178
+ document.querySelectorAll(".prefix").forEach((prefix) => {
179
+ prefix.setAttribute("y", "28");
180
+ });
181
+ document
182
+ .querySelectorAll(".fix")
183
+ .forEach((fix) => fix.setAttribute("y", "38"));
184
+ }
185
+
186
+ }, [chartData]);
187
+
188
+ return (
189
+ <HighchartsReact
190
+ containerProps={{
191
+ className: classnames(css, globalProps(props)),
192
+ id: id,
193
+ ...ariaProps,
194
+ ...dataProps,
195
+ }}
196
+ highcharts={Highcharts}
197
+ options={options}
198
+ />
199
+ );
200
+ };
201
+
202
+ export default Gauge;
@@ -19,7 +19,7 @@
19
19
  <%= pb_rails("gauge", props: {
20
20
  chart_data: [{ name: "Name", value: 10 }],
21
21
  disable_animation: true,
22
- height: '100%',
22
+ height: '150',
23
23
  id: "gauge-complex",
24
24
  suffix: "%"
25
25
  }) %>
@@ -71,26 +71,26 @@ const GaugeComplex = (props) => (
71
71
  orientation="column"
72
72
  wrap
73
73
  >
74
- <Body
75
- color="light"
76
- text="% Abandoned"
77
- />
74
+ <Body
75
+ color="light"
76
+ text="% Abandoned"
77
+ />
78
78
  <Flex wrap>
79
79
  <FlexItem
80
80
  fixedSize="150px"
81
81
  overflow="hidden"
82
82
  shrink
83
- >
83
+ >
84
84
  <Gauge
85
85
  chartData={data}
86
86
  disableAnimation
87
- height="100%"
87
+ height="150"
88
88
  id="gauge-complex"
89
89
  suffix="%"
90
90
  {...props}
91
91
  />
92
- </FlexItem>
93
- </Flex>
92
+ </FlexItem>
93
+ </Flex>
94
94
  </Flex>
95
95
  </Flex>
96
96
  </Card>
@@ -1,12 +1,2 @@
1
- <%= content_tag(:div, "",
2
- id: object.id,
3
- data: object.data,
4
- class: object.classname) %>
5
- <% content_for :pb_js do %>
6
- <%= javascript_tag do %>
7
- window.addEventListener('DOMContentLoaded', function() {
8
- new pbChart('.selector', <%= object.chart_options %>)
9
- })
10
- <% end %>
11
- <% end %>
1
+ <%= react_component('Gauge', object.chart_options) %>
12
2
 
@@ -22,15 +22,10 @@ module Playbook
22
22
  prop :max, type: Playbook::Props::Numeric, default: 100
23
23
  prop :colors, type: Playbook::Props::Array, default: []
24
24
 
25
- def chart_data_formatted
26
- chart_data.map { |hash| hash[:y] = hash.delete :value }
27
- chart_data
28
- end
29
-
30
25
  def chart_options
31
26
  {
32
27
  id: id,
33
- chartData: chart_data_formatted,
28
+ chartData: chart_data,
34
29
  circumference: full_circle ? [0, 360] : [-100, 100],
35
30
  dark: dark ? "dark" : "",
36
31
  disableAnimation: disable_animation,
@@ -43,9 +38,9 @@ module Playbook
43
38
  showLabels: show_labels,
44
39
  style: style,
45
40
  tooltipHtml: tooltip_html,
46
- type: "gauge",
41
+ type: style,
47
42
  colors: colors,
48
- }.to_json.html_safe
43
+ }
49
44
  end
50
45
 
51
46
  def classname
@@ -0,0 +1,148 @@
1
+ import React, { useState, useEffect } from "react";
2
+ import classnames from "classnames";
3
+ import { globalProps } from "../utilities/globalProps";
4
+ import { buildAriaProps, buildDataProps } from "../utilities/props";
5
+
6
+ import HighchartsReact from "highcharts-react-official";
7
+ import Highcharts from "highcharts";
8
+ import { highchartsTheme } from "../pb_dashboard/pbChartsLightTheme";
9
+ import { highchartsDarkTheme } from "../pb_dashboard/pbChartsDarkTheme";
10
+ import mapColors from "../pb_dashboard/pbChartsColorsHelper";
11
+
12
+ type LineGraphProps = {
13
+ align?: "left" | "right" | "center";
14
+ axisTitle?: string;
15
+ dark?: Boolean;
16
+ xAxisCategories: [];
17
+ yAxisMin: number;
18
+ yAxisMax: number;
19
+ className?: string;
20
+ chartData: {
21
+ name: string;
22
+ data: number[];
23
+ }[];
24
+ gradient?: boolean;
25
+ id: string;
26
+ pointStart: number;
27
+ subTitle?: string;
28
+ title: string;
29
+ type?: string;
30
+ legend?: boolean;
31
+ toggleLegendClick?: boolean;
32
+ height?: string;
33
+ colors: string[];
34
+ layout?: "horizontal" | "vertical" | "proximate";
35
+ verticalAlign?: "top" | "middle" | "bottom";
36
+ x?: number;
37
+ y?: number;
38
+ aria?: { [key: string]: string };
39
+ data?: { [key: string]: string };
40
+ };
41
+
42
+ const LineGraph = ({
43
+ aria = {},
44
+ data = {},
45
+ align = "center",
46
+ className = "pb_bar_graph",
47
+ dark = false,
48
+ gradient = false,
49
+ type = "line",
50
+ id,
51
+ legend = false,
52
+ toggleLegendClick = true,
53
+ layout = "horizontal",
54
+ verticalAlign = "bottom",
55
+ x = 0,
56
+ y = 0,
57
+ axisTitle,
58
+ xAxisCategories,
59
+ yAxisMin,
60
+ yAxisMax,
61
+ chartData,
62
+ pointStart,
63
+ subTitle,
64
+ title,
65
+ height,
66
+ colors = [],
67
+ ...props
68
+ }: LineGraphProps) => {
69
+ const ariaProps = buildAriaProps(aria);
70
+ const dataProps = buildDataProps(data);
71
+ const setupTheme = () => {
72
+ dark
73
+ ? Highcharts.setOptions(highchartsDarkTheme)
74
+ : Highcharts.setOptions(highchartsTheme);
75
+ };
76
+ setupTheme();
77
+
78
+ const staticOptions = {
79
+ title: {
80
+ text: title,
81
+ },
82
+ chart: {
83
+ height: height,
84
+ type: type,
85
+ },
86
+ subtitle: {
87
+ text: subTitle,
88
+ },
89
+ yAxis: {
90
+ min: yAxisMin,
91
+ max: yAxisMax,
92
+ title: {
93
+ text: axisTitle,
94
+ },
95
+ },
96
+ xAxis: {
97
+ categories: xAxisCategories,
98
+ },
99
+ legend: {
100
+ enabled: legend,
101
+ align: align,
102
+ verticalAlign: verticalAlign,
103
+ layout: layout,
104
+ x: x,
105
+ y: y,
106
+ },
107
+ colors:
108
+ colors !== undefined && colors.length > 0
109
+ ? mapColors(colors)
110
+ : highchartsTheme.colors,
111
+ plotOptions: {
112
+ series: {
113
+ pointStart: pointStart,
114
+ events: {},
115
+ dataLabels: {
116
+ enabled: false,
117
+ },
118
+ },
119
+ },
120
+ series: chartData,
121
+ credits: false,
122
+ };
123
+
124
+ if (!toggleLegendClick) {
125
+ staticOptions.plotOptions.series.events = { legendItemClick: () => false };
126
+ }
127
+
128
+ const [options, setOptions] = useState({});
129
+
130
+ useEffect(() => {
131
+ setOptions({ ...staticOptions });
132
+ }, [chartData]);
133
+
134
+ return (
135
+ <HighchartsReact
136
+ containerProps={{
137
+ className: classnames(globalProps(props), className),
138
+ id: id,
139
+ ...ariaProps,
140
+ ...dataProps,
141
+ }}
142
+ highcharts={Highcharts}
143
+ options={options}
144
+ />
145
+ );
146
+ };
147
+
148
+ export default LineGraph;
@@ -0,0 +1,68 @@
1
+ @import "tokens/colors";
2
+ @import "tokens/typography";
3
+ @import "tokens/border_radius";
4
+ @import "tokens/shadows";
5
+
6
+ .pb_pagination {
7
+ display: inline-block;
8
+ border-radius: $border_rad_light;
9
+ border: 1px solid $border_light;
10
+ background-color: $white;
11
+ padding: 3px 0px 3.6px 0px;
12
+ li {
13
+ display: inline;
14
+ > a, li > span {
15
+ padding: 7px 13px;
16
+ text-decoration: none;
17
+ margin-left: -1px;
18
+ border: 0 !important;
19
+ }}
20
+ li:first-child > a, li:first-child > span {
21
+ padding: 7px 13px;
22
+ margin-left: .5px;
23
+ border-right: 1px solid $border_light !important;
24
+ z-index: 2;
25
+ }
26
+ li:last-child > a, li:last-child > span {
27
+ padding: 7px 13px;
28
+ margin-right: .5px;
29
+ border-left: 1px solid $border_light !important;
30
+ z-index: 2;
31
+ }
32
+ a {
33
+ color: $text_lt_default !important;
34
+ font-size: $text_small;
35
+ font-weight: $regular;
36
+ border: none;
37
+
38
+ &:hover {
39
+ background-color: $active_light;
40
+ color: $primary !important;
41
+ border-radius: $border_rad_light;
42
+ }
43
+
44
+ &:focus {
45
+ outline: 1px solid $primary !important;
46
+ border-radius: $border_rad_light;
47
+ outline-offset: -1px;
48
+ }
49
+ }
50
+ .active > span {
51
+ background-color: $primary !important;
52
+ border-radius: $border_rad_light;
53
+ color: #fff;
54
+ padding: 7px 10px;
55
+ border: 0 !important;
56
+ text-decoration: none;
57
+ font-weight: $bold;
58
+ font-size: $text_small;
59
+
60
+ &:hover {
61
+ box-shadow: $shadow_deeper;
62
+ }
63
+ }
64
+ .disabled > span {
65
+ padding: 7px 10px;
66
+ font-size: $text_small;
67
+ }
68
+ }
@@ -0,0 +1,41 @@
1
+
2
+
3
+ /* @flow */
4
+
5
+ import React from 'react'
6
+ import classnames from 'classnames'
7
+ import { buildAriaProps, buildCss, buildDataProps } from '../utilities/props'
8
+ import { globalProps } from '../utilities/globalProps'
9
+
10
+ type PaginationProps = {
11
+ aria?: { [key: string]: string },
12
+ className?: string,
13
+ data?: { [key: string]: string },
14
+ id?: string,
15
+ }
16
+
17
+ const Pagination = (props: PaginationProps) => {
18
+ const {
19
+ aria = {},
20
+ className,
21
+ data = {},
22
+ id,
23
+ } = props
24
+
25
+ const ariaProps = buildAriaProps(aria)
26
+ const dataProps = buildDataProps(data)
27
+ const classes = classnames(buildCss('pb_pagination'), globalProps(props), className)
28
+
29
+ return (
30
+ <div
31
+ {...ariaProps}
32
+ {...dataProps}
33
+ className={classes}
34
+ id={id}
35
+ >
36
+ {className}
37
+ </div>
38
+ )
39
+ }
40
+
41
+ export default Pagination
@@ -0,0 +1,28 @@
1
+ <% @data = [{
2
+ first_name: 'Jon',
3
+ last_name: 'Ron',
4
+ email: "jon@mail.com",
5
+ id: 1,
6
+ }, {
7
+ first_name: 'Sam',
8
+ last_name: 'Bob',
9
+ email: "sam@mail.com",
10
+ id: 2,
11
+ }, {
12
+ first_name: 'Nick',
13
+ last_name: 'Jack',
14
+ email: "nick@mail.com",
15
+ id: 3,
16
+ }, {
17
+ first_name: 'Jake',
18
+ last_name: 'Wade',
19
+ email: "jon@mail.com",
20
+ id: 4,
21
+ }, {
22
+ first_name: 'Blake',
23
+ last_name: 'Chad',
24
+ email: "jon@mail.com",
25
+ id: 5,
26
+ }] %>
27
+
28
+ <%= pb_rails("pagination", props: { data: @data}) %>
@@ -0,0 +1,12 @@
1
+ import React from 'react'
2
+ import Pagination from '../_pagination'
3
+
4
+ const PaginationDefault = (props) => (
5
+ <div>
6
+ <Pagination
7
+ {...props}
8
+ />
9
+ </div>
10
+ )
11
+
12
+ export default PaginationDefault
@@ -0,0 +1,9 @@
1
+ examples:
2
+
3
+ rails:
4
+ - pagination_default: Default
5
+
6
+
7
+ # react:
8
+ # - pagination_default: Default
9
+
@@ -0,0 +1 @@
1
+ export { default as PaginationDefault } from './_pagination_default.jsx'
@@ -0,0 +1,7 @@
1
+ <%= content_tag(:div,
2
+ aria: object.aria,
3
+ class: object.classname,
4
+ data: object.data,
5
+ id: object.id) do %>
6
+ <%= will_paginate object.page_data, renderer: Playbook::Pagination::Rails %>
7
+ <% end %>
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "will_paginate/array"
4
+ module Playbook
5
+ module PbPagination
6
+ class Pagination < ::Playbook::KitBase
7
+ prop :data, type: Playbook::Props::Array,
8
+ default: []
9
+ def page_data
10
+ new_user_array = []
11
+ data.each do |user|
12
+ new_user_array.push(user)
13
+ end
14
+ new_user_array.paginate(page: params[:page], per_page: 3)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,17 @@
1
+ import { renderKit } from '../utilities/test-utils'
2
+
3
+ import { Pagination } from '../'
4
+
5
+ /* See these resources for more testing info:
6
+ - https://github.com/testing-library/jest-dom#usage for useage and examples
7
+ - https://jestjs.io/docs/en/using-matchers
8
+ */
9
+
10
+ test('generated scaffold test - update me', () => {
11
+ const props = {
12
+ data: { testid: 'default' }
13
+ }
14
+
15
+ const kit = renderKit(Pagination , props)
16
+ expect(kit).toBeInTheDocument()
17
+ })