playbook_ui 12.1.0 → 12.3.0.pre.alpha.patchtest1
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.
- checksums.yaml +4 -4
- data/app/pb_kits/playbook/_playbook.scss +3 -0
- data/app/pb_kits/playbook/data/menu.yml +1 -0
- data/app/pb_kits/playbook/index.js +3 -2
- data/app/pb_kits/playbook/pb_bar_graph/_bar_graph.tsx +10 -10
- data/app/pb_kits/playbook/pb_button/_button.scss +0 -5
- data/app/pb_kits/playbook/pb_button/_button.tsx +4 -0
- data/app/pb_kits/playbook/pb_button/_button_mixins.scss +39 -4
- data/app/pb_kits/playbook/pb_button/button.rb +2 -0
- data/app/pb_kits/playbook/pb_button/docs/_button_accessibility.jsx +1 -0
- data/app/pb_kits/playbook/pb_button/docs/_button_block_content.jsx +1 -0
- data/app/pb_kits/playbook/pb_button/docs/_button_default.jsx +4 -0
- data/app/pb_kits/playbook/pb_button/docs/_button_form.jsx +1 -0
- data/app/pb_kits/playbook/pb_button/docs/_button_full_width.jsx +1 -0
- data/app/pb_kits/playbook/pb_button/docs/_button_icon_options.html.erb +2 -2
- data/app/pb_kits/playbook/pb_button/docs/_button_icon_options.jsx +4 -0
- data/app/pb_kits/playbook/pb_button/docs/_button_link.html.erb +3 -3
- data/app/pb_kits/playbook/pb_button/docs/_button_link.jsx +6 -0
- data/app/pb_kits/playbook/pb_button/docs/_button_loading.html.erb +3 -3
- data/app/pb_kits/playbook/pb_button/docs/_button_loading.jsx +6 -0
- data/app/pb_kits/playbook/pb_button/docs/_button_options.jsx +1 -0
- data/app/pb_kits/playbook/pb_button/docs/_button_size.html.erb +3 -3
- data/app/pb_kits/playbook/pb_button/docs/_button_size.jsx +6 -0
- data/app/pb_kits/playbook/pb_checkbox/_checkbox.scss +26 -19
- data/app/pb_kits/playbook/pb_circle_icon_button/_circle_icon_button.scss +24 -0
- data/app/pb_kits/playbook/pb_dashboard/pbChartsDarkTheme.ts +2 -0
- data/app/pb_kits/playbook/pb_form_group/_form_group.scss +10 -2
- data/app/pb_kits/playbook/pb_map/_map.scss +8 -0
- data/app/pb_kits/playbook/pb_map/_map.tsx +40 -0
- data/app/pb_kits/playbook/pb_map/docs/_map_default.jsx +52 -0
- data/app/pb_kits/playbook/pb_map/docs/_map_default.md +13 -0
- data/app/pb_kits/playbook/pb_map/docs/_map_with_plugin.jsx +64 -0
- data/app/pb_kits/playbook/pb_map/docs/_map_with_plugin.md +8 -0
- data/app/pb_kits/playbook/pb_map/docs/example.yml +7 -0
- data/app/pb_kits/playbook/pb_map/docs/index.js +2 -0
- data/app/pb_kits/playbook/pb_map/map.test.jsx +17 -0
- data/app/pb_kits/playbook/pb_progress_simple/{_progress_simple.jsx → _progress_simple.tsx} +7 -5
- data/app/pb_kits/playbook/pb_progress_simple/progress_simple.test.js +120 -0
- data/app/pb_kits/playbook/pb_selectable_card/_selectable_card.scss +4 -9
- data/app/pb_kits/playbook/pb_stat_change/_stat_change.tsx +66 -0
- data/app/pb_kits/playbook/pb_stat_change/stat_change.test.js +41 -0
- data/app/pb_kits/playbook/pb_stat_value/{_stat_value.jsx → _stat_value.tsx} +4 -6
- data/app/pb_kits/playbook/pb_stat_value/docs/_stat_value_unit.jsx +1 -1
- data/app/pb_kits/playbook/pb_stat_value/stat_value.test.js +27 -0
- data/app/pb_kits/playbook/pb_time_stacked/{_time_stacked.jsx → _time_stacked.tsx} +3 -5
- data/app/pb_kits/playbook/pb_time_stacked/docs/_time_stacked_default.jsx +1 -1
- data/app/pb_kits/playbook/pb_time_stacked/docs/index.js +1 -1
- data/app/pb_kits/playbook/pb_timestamp/{_timestamp.jsx → _timestamp.tsx} +5 -7
- data/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_align.jsx +1 -1
- data/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_default.jsx +1 -1
- data/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_elapsed.jsx +1 -1
- data/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_timezones.jsx +1 -1
- data/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_updated.jsx +1 -1
- data/app/pb_kits/playbook/pb_tooltip/_tooltip.tsx +36 -28
- data/app/pb_kits/playbook/pb_tooltip/docs/_tooltip_default_react.jsx +1 -0
- data/app/pb_kits/playbook/pb_tooltip/tooltip.test.jsx +14 -0
- data/app/pb_kits/playbook/pb_typeahead/_typeahead.jsx +11 -2
- data/app/pb_kits/playbook/pb_typeahead/_typeahead.scss +0 -2
- data/app/pb_kits/playbook/pb_typeahead/_typeahead.test.jsx +95 -0
- data/app/pb_kits/playbook/pb_typeahead/components/ClearIndicator.jsx +1 -1
- data/app/pb_kits/playbook/pb_typeahead/components/Control.jsx +1 -0
- data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_error_state.html.erb +19 -0
- data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_error_state.jsx +39 -0
- data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_error_state.md +1 -0
- data/app/pb_kits/playbook/pb_typeahead/docs/example.yml +2 -0
- data/app/pb_kits/playbook/pb_typeahead/docs/index.js +1 -0
- data/app/pb_kits/playbook/pb_typeahead/typeahead.rb +3 -0
- data/app/pb_kits/playbook/playbook-doc.js +2 -0
- data/app/pb_kits/playbook/tokens/_colors.scss +6 -2
- data/app/pb_kits/playbook/utilities/_focus.scss +12 -0
- data/lib/playbook/version.rb +2 -2
- metadata +26 -9
- data/app/pb_kits/playbook/pb_stat_change/_stat_change.jsx +0 -63
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import classnames from 'classnames'
|
|
3
|
+
import { buildAriaProps, buildCss, buildDataProps } from '../utilities/props'
|
|
4
|
+
import { globalProps } from '../utilities/globalProps'
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
type MapProps = {
|
|
8
|
+
aria?: { [key: string]: string },
|
|
9
|
+
children?: React.ReactChild[] | React.ReactNode,
|
|
10
|
+
className?: string,
|
|
11
|
+
data?: { [key: string]: string },
|
|
12
|
+
id?: string,
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const Map = (props: MapProps) => {
|
|
16
|
+
const {
|
|
17
|
+
aria = {},
|
|
18
|
+
children,
|
|
19
|
+
className,
|
|
20
|
+
data = {},
|
|
21
|
+
id,
|
|
22
|
+
} = props
|
|
23
|
+
|
|
24
|
+
const ariaProps = buildAriaProps(aria)
|
|
25
|
+
const dataProps = buildDataProps(data)
|
|
26
|
+
const classes = classnames(buildCss('pb_map'), globalProps(props), className)
|
|
27
|
+
|
|
28
|
+
return (
|
|
29
|
+
<div
|
|
30
|
+
{...ariaProps}
|
|
31
|
+
{...dataProps}
|
|
32
|
+
className={classes}
|
|
33
|
+
id={id}
|
|
34
|
+
>
|
|
35
|
+
{children}
|
|
36
|
+
</div>
|
|
37
|
+
)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export default Map
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import React, { useRef, useEffect } from 'react'
|
|
2
|
+
import { Map } from '../../'
|
|
3
|
+
|
|
4
|
+
import maplibregl from 'maplibre-gl'
|
|
5
|
+
|
|
6
|
+
const MapDefault = () => {
|
|
7
|
+
|
|
8
|
+
const mapContainerRef = useRef(null)
|
|
9
|
+
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
if (!maplibregl.supported()) {
|
|
12
|
+
alert('Your browser does not support MapLibre GL');
|
|
13
|
+
} else {
|
|
14
|
+
const map = new maplibregl.Map({
|
|
15
|
+
container: mapContainerRef.current,
|
|
16
|
+
style: 'https://basemaps.cartocdn.com/gl/positron-gl-style/style.json',
|
|
17
|
+
center: [-75.379143, 39.831200],
|
|
18
|
+
zoom: 13,
|
|
19
|
+
})
|
|
20
|
+
//set marker/pin
|
|
21
|
+
/* eslint-disable-next-line */
|
|
22
|
+
const marker = new maplibregl.Marker({
|
|
23
|
+
color: "#0056CF",
|
|
24
|
+
}).setLngLat([-75.379143, 39.831200])
|
|
25
|
+
.setPopup(new maplibregl.Popup({className: 'map_popup', closeButton: false}).setHTML(`<h4 class="pb_title_kit_size_4">Hello World!</h4>`)) // add popup
|
|
26
|
+
.addTo(map);
|
|
27
|
+
|
|
28
|
+
//add zoom controls
|
|
29
|
+
map.addControl(new maplibregl.NavigationControl({showCompass: false}))
|
|
30
|
+
|
|
31
|
+
// disable map zoom when using scroll
|
|
32
|
+
map.scrollZoom.disable();
|
|
33
|
+
|
|
34
|
+
}
|
|
35
|
+
}, [])
|
|
36
|
+
return (
|
|
37
|
+
<Map>
|
|
38
|
+
<div
|
|
39
|
+
ref={mapContainerRef}
|
|
40
|
+
style={{
|
|
41
|
+
position: 'absolute',
|
|
42
|
+
left: 0,
|
|
43
|
+
right: 0,
|
|
44
|
+
top: 0,
|
|
45
|
+
bottom: 0,
|
|
46
|
+
}}
|
|
47
|
+
/>
|
|
48
|
+
</Map>
|
|
49
|
+
)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export default MapDefault
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
This kit provides a wrapping class to place around the MapLibre library. Complete docs for using the library can be found [here](https://maplibre.org/maplibre-gl-js-docs/api/).
|
|
2
|
+
|
|
3
|
+
Basic setup to start using MapLibre:
|
|
4
|
+
- Install the npm package using `yarn add maplibre-gl`
|
|
5
|
+
- Include a link to the CSS file as a CDN in your stylesheet using the following syntax:
|
|
6
|
+
`@import url("https://unpkg.com/maplibre-gl@2.4.0/dist/maplibre-gl.css");`
|
|
7
|
+
or include it as a link in the <head> tag `<link href='https://unpkg.com/maplibre-gl@2.4.0/dist/maplibre-gl.css' rel='stylesheet' />`
|
|
8
|
+
- To use Maplibre, you must also set a height on the containing div.
|
|
9
|
+
- You can now use MapLibre within the Map Kit as shown in this example.
|
|
10
|
+
|
|
11
|
+
__Notes__ :
|
|
12
|
+
- The MapLibre Marker allows us to pass it a HEX value as a color prop. In these doc examples we are using our primary color for the Marker.
|
|
13
|
+
- `scrollZoom` has been disabled in these doc examples for page usability
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import React, { useRef, useEffect } from 'react'
|
|
2
|
+
import { Map } from '../../'
|
|
3
|
+
import maplibregl from 'maplibre-gl'
|
|
4
|
+
import MapboxDraw from "@mapbox/mapbox-gl-draw";
|
|
5
|
+
|
|
6
|
+
const MapWithPlugin = () => {
|
|
7
|
+
|
|
8
|
+
const mapContainerRef = useRef(null)
|
|
9
|
+
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
if (!maplibregl.supported()) {
|
|
12
|
+
alert('Your browser does not support MapLibre GL');
|
|
13
|
+
} else {
|
|
14
|
+
const map = new maplibregl.Map({
|
|
15
|
+
container: mapContainerRef.current,
|
|
16
|
+
style: 'https://basemaps.cartocdn.com/gl/positron-gl-style/style.json',
|
|
17
|
+
center: [-75.379143, 39.831200],
|
|
18
|
+
zoom: 13,
|
|
19
|
+
})
|
|
20
|
+
//set marker/pin
|
|
21
|
+
/* eslint-disable-next-line */
|
|
22
|
+
const marker = new maplibregl.Marker({
|
|
23
|
+
color: "#0056CF",
|
|
24
|
+
}).setLngLat([-75.379143, 39.831200])
|
|
25
|
+
.setPopup(new maplibregl.Popup({className: 'map_popup', closeButton: false}).setHTML(`<h4 class="pb_title_kit_size_4">Hello World!</h4>`)) // add popup
|
|
26
|
+
.addTo(map);
|
|
27
|
+
|
|
28
|
+
//add zoom controls
|
|
29
|
+
map.addControl(new maplibregl.NavigationControl({showCompass: false}))
|
|
30
|
+
|
|
31
|
+
// disable map zoom when using scroll
|
|
32
|
+
map.scrollZoom.disable();
|
|
33
|
+
|
|
34
|
+
//Add polygon draw button using map-box-gl-draw plugin
|
|
35
|
+
var draw = new MapboxDraw({
|
|
36
|
+
displayControlsDefault: false,
|
|
37
|
+
controls: {
|
|
38
|
+
polygon: true,
|
|
39
|
+
trash: true
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
map.addControl(draw);
|
|
43
|
+
}
|
|
44
|
+
}, [])
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
return (
|
|
49
|
+
<Map>
|
|
50
|
+
<div
|
|
51
|
+
ref={mapContainerRef}
|
|
52
|
+
style={{
|
|
53
|
+
position: 'absolute',
|
|
54
|
+
left: 0,
|
|
55
|
+
right: 0,
|
|
56
|
+
top: 0,
|
|
57
|
+
bottom: 0,
|
|
58
|
+
}}
|
|
59
|
+
/>
|
|
60
|
+
</Map>
|
|
61
|
+
)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export default MapWithPlugin
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
Various plugins are available for use with MapLibre, one of which is the [mapbox-gl-draw](https://github.com/mapbox/mapbox-gl-draw). This plugin is recommended by MapLibre if you need to add the functionality of drawing polygons on the map.
|
|
2
|
+
|
|
3
|
+
To test this tool:
|
|
4
|
+
- Click the "draw box" icon to activate the polygon tool
|
|
5
|
+
- Click on a spot on the map to start drawing
|
|
6
|
+
- Continue clicking to create new points, defining the boundaries of the polygon
|
|
7
|
+
- Press enter or re-click the first point to finish the polygon
|
|
8
|
+
- Once drawn, polygons can be selected on click and then moved, by dragging-and-dropping the entire shape; resized, by dragging-and-dropping any boundary point(s); or deleted, by clicking the "trash" button.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { renderKit } from '../utilities/test-utils'
|
|
2
|
+
|
|
3
|
+
import { Map } 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(Map , props)
|
|
16
|
+
expect(kit).toBeInTheDocument()
|
|
17
|
+
})
|
|
@@ -1,16 +1,15 @@
|
|
|
1
|
-
/* @flow */
|
|
2
1
|
import React from 'react'
|
|
3
2
|
import classnames from 'classnames'
|
|
4
|
-
import { buildCss } from '../utilities/props'
|
|
3
|
+
import { buildCss, buildDataProps } from '../utilities/props'
|
|
5
4
|
import { globalProps } from '../utilities/globalProps'
|
|
6
5
|
|
|
7
6
|
type ProgressSimpleProps = {
|
|
8
7
|
align?: "left" | "center" | "right",
|
|
9
|
-
className?: string |
|
|
8
|
+
className?: string | string[],
|
|
10
9
|
dark?: boolean,
|
|
11
10
|
data?: string,
|
|
12
11
|
id?: string,
|
|
13
|
-
max?:
|
|
12
|
+
max?: number,
|
|
14
13
|
muted: boolean,
|
|
15
14
|
percent: string,
|
|
16
15
|
value: number,
|
|
@@ -23,6 +22,7 @@ const ProgressSimple = (props: ProgressSimpleProps) => {
|
|
|
23
22
|
align,
|
|
24
23
|
className,
|
|
25
24
|
dark = false,
|
|
25
|
+
data ={},
|
|
26
26
|
max,
|
|
27
27
|
muted = false,
|
|
28
28
|
percent = '',
|
|
@@ -34,6 +34,7 @@ const ProgressSimple = (props: ProgressSimpleProps) => {
|
|
|
34
34
|
width: width,
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
+
const dataProps = buildDataProps(data)
|
|
37
38
|
const variantStyle = variant == 'default' ? '' : variant
|
|
38
39
|
|
|
39
40
|
const valueStyles = {
|
|
@@ -52,7 +53,8 @@ const ProgressSimple = (props: ProgressSimpleProps) => {
|
|
|
52
53
|
)
|
|
53
54
|
|
|
54
55
|
return (
|
|
55
|
-
<div
|
|
56
|
+
<div {...dataProps}
|
|
57
|
+
className={wrapperClass}>
|
|
56
58
|
<div
|
|
57
59
|
className={kitClass}
|
|
58
60
|
data-value={value}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { render, screen, cleanup } from '../utilities/test-utils'
|
|
3
|
+
|
|
4
|
+
import ProgressSimple from './_progress_simple'
|
|
5
|
+
|
|
6
|
+
const testId = "progress-simple-test"
|
|
7
|
+
|
|
8
|
+
test('renders default class name and percentage', () => {
|
|
9
|
+
render(
|
|
10
|
+
<div>
|
|
11
|
+
<ProgressSimple
|
|
12
|
+
data={{ testid: testId }}
|
|
13
|
+
percent={45}
|
|
14
|
+
/>
|
|
15
|
+
</div>
|
|
16
|
+
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
const kit = screen.getByTestId(testId)
|
|
20
|
+
const progress = kit.querySelector(".progress_simple_value")
|
|
21
|
+
|
|
22
|
+
expect(kit).toHaveClass('pb_progress_simple_wrapper')
|
|
23
|
+
expect(progress).toHaveStyle("width: 45%")
|
|
24
|
+
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
test('renders values', () => {
|
|
28
|
+
render(
|
|
29
|
+
<div>
|
|
30
|
+
<ProgressSimple
|
|
31
|
+
data={{ testid: testId }}
|
|
32
|
+
max='10'
|
|
33
|
+
value='2'
|
|
34
|
+
/>
|
|
35
|
+
</div>
|
|
36
|
+
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
const kit = screen.getByTestId(testId)
|
|
40
|
+
const progress = kit.querySelector(".progress_simple_value")
|
|
41
|
+
expect(progress).toHaveStyle("width: 20%")
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
test('renders progress bar width', () => {
|
|
45
|
+
render(
|
|
46
|
+
<div>
|
|
47
|
+
<ProgressSimple
|
|
48
|
+
data={{ testid: testId }}
|
|
49
|
+
percentage={40}
|
|
50
|
+
width="100px"
|
|
51
|
+
/>
|
|
52
|
+
</div>
|
|
53
|
+
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
const kit = screen.getByTestId(testId)
|
|
57
|
+
const progress = kit.querySelector(".pb_progress_simple_kit")
|
|
58
|
+
expect(progress).toHaveStyle("width: 100px")
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
test('renders color variants', () => {
|
|
62
|
+
[
|
|
63
|
+
"positive",
|
|
64
|
+
"negative",
|
|
65
|
+
"warning"
|
|
66
|
+
].forEach((colorVariant) => {
|
|
67
|
+
|
|
68
|
+
render(
|
|
69
|
+
<div>
|
|
70
|
+
<ProgressSimple
|
|
71
|
+
data={{ testid: testId }}
|
|
72
|
+
percentage={40}
|
|
73
|
+
variant={colorVariant}
|
|
74
|
+
/>
|
|
75
|
+
</div>
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
const kit = screen.getByTestId(testId)
|
|
79
|
+
const progress = kit.querySelector(`.pb_progress_simple_kit_${colorVariant}`)
|
|
80
|
+
expect(progress).toBeInTheDocument()
|
|
81
|
+
|
|
82
|
+
cleanup()
|
|
83
|
+
})
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
test('renders muted prop', () => {
|
|
87
|
+
render(
|
|
88
|
+
<div>
|
|
89
|
+
<ProgressSimple
|
|
90
|
+
data={{ testid: testId }}
|
|
91
|
+
muted
|
|
92
|
+
percentage={40}
|
|
93
|
+
/>
|
|
94
|
+
</div>
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
const kit = screen.getByTestId(testId)
|
|
98
|
+
const progress = kit.querySelector('.pb_progress_simple_kit_muted')
|
|
99
|
+
expect(progress).toBeInTheDocument()
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
test('renders align prop', () => {
|
|
103
|
+
[
|
|
104
|
+
"left",
|
|
105
|
+
"center",
|
|
106
|
+
"right"
|
|
107
|
+
].forEach((alignProp) => {
|
|
108
|
+
render(
|
|
109
|
+
<ProgressSimple
|
|
110
|
+
align={alignProp}
|
|
111
|
+
data={{ testid: testId }}
|
|
112
|
+
percentage={45}
|
|
113
|
+
/>
|
|
114
|
+
)
|
|
115
|
+
const kit = screen.getByTestId(testId)
|
|
116
|
+
expect(kit).toHaveClass(`pb_progress_simple_wrapper_${alignProp}`)
|
|
117
|
+
|
|
118
|
+
cleanup()
|
|
119
|
+
})
|
|
120
|
+
})
|
|
@@ -19,12 +19,11 @@ $pb_selectable_card_border: 2px;
|
|
|
19
19
|
display: inherit;
|
|
20
20
|
flex-direction: inherit;
|
|
21
21
|
padding: 1px;
|
|
22
|
-
transition-property: all;
|
|
23
|
-
transition-duration: $transition_short;
|
|
24
|
-
transition-timing-function: $easeIn;
|
|
25
22
|
}
|
|
26
23
|
|
|
27
24
|
@include pb_card;
|
|
25
|
+
transition-property: none;
|
|
26
|
+
transition-duration: 0s;
|
|
28
27
|
background-color: $white;
|
|
29
28
|
padding: $space_sm;
|
|
30
29
|
margin-bottom: $space_sm;
|
|
@@ -55,9 +54,6 @@ $pb_selectable_card_border: 2px;
|
|
|
55
54
|
top: -($pb_selectable_card_indicator_size/2);
|
|
56
55
|
right: -($pb_selectable_card_indicator_size/2);
|
|
57
56
|
opacity: 0;
|
|
58
|
-
transition-property: opacity;
|
|
59
|
-
transition-duration: $transition_short;
|
|
60
|
-
transition-timing-function: $easeIn;
|
|
61
57
|
}
|
|
62
58
|
}
|
|
63
59
|
|
|
@@ -77,6 +73,8 @@ $pb_selectable_card_border: 2px;
|
|
|
77
73
|
|
|
78
74
|
position: relative;
|
|
79
75
|
@include pb_card_selected;
|
|
76
|
+
transition-property: none;
|
|
77
|
+
transition-duration: 0s;
|
|
80
78
|
|
|
81
79
|
.pb_selectable_card_circle {
|
|
82
80
|
opacity: $opacity_10;
|
|
@@ -127,9 +125,6 @@ $pb_selectable_card_border: 2px;
|
|
|
127
125
|
|
|
128
126
|
.separator {
|
|
129
127
|
align-self: stretch;
|
|
130
|
-
transition-property: all;
|
|
131
|
-
transition-duration: $transition_short;
|
|
132
|
-
transition-timing-function: $easeIn;
|
|
133
128
|
width: 1px;
|
|
134
129
|
margin-right: 1px;
|
|
135
130
|
margin-top: -1px;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import classnames from 'classnames'
|
|
3
|
+
|
|
4
|
+
import { buildCss } from '../utilities/props'
|
|
5
|
+
import { globalProps } from '../utilities/globalProps'
|
|
6
|
+
|
|
7
|
+
import Body from '../pb_body/_body'
|
|
8
|
+
import Icon from '../pb_icon/_icon'
|
|
9
|
+
|
|
10
|
+
const statusMap: {neutral: 'neutral', decrease: 'negative' ,increase: 'positive'} = {
|
|
11
|
+
increase: 'positive',
|
|
12
|
+
decrease: 'negative',
|
|
13
|
+
neutral: 'neutral',
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const iconMap = {
|
|
17
|
+
increase: 'arrow-up',
|
|
18
|
+
decrease: 'arrow-down',
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
type StatChangeProps = {
|
|
22
|
+
change?: 'increase' | 'decrease' | 'neutral',
|
|
23
|
+
className?: string,
|
|
24
|
+
icon?: string,
|
|
25
|
+
id?: string,
|
|
26
|
+
value?: string | number,
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const StatChange = (props: StatChangeProps): React.ReactElement => {
|
|
30
|
+
const { change = 'neutral', className, icon, id, value } = props
|
|
31
|
+
const status = statusMap[change as keyof typeof statusMap]
|
|
32
|
+
let returnedIcon = iconMap[change as keyof typeof iconMap]
|
|
33
|
+
if (icon) {
|
|
34
|
+
returnedIcon = icon
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return (
|
|
38
|
+
<>
|
|
39
|
+
{value &&
|
|
40
|
+
<div
|
|
41
|
+
className={classnames(
|
|
42
|
+
buildCss('pb_stat_change_kit', status),
|
|
43
|
+
globalProps(props),
|
|
44
|
+
className
|
|
45
|
+
)}
|
|
46
|
+
id={id}
|
|
47
|
+
>
|
|
48
|
+
<Body status={status}>
|
|
49
|
+
{returnedIcon &&
|
|
50
|
+
<>
|
|
51
|
+
<Icon
|
|
52
|
+
fixed_width
|
|
53
|
+
icon={returnedIcon}
|
|
54
|
+
/>
|
|
55
|
+
{' '}
|
|
56
|
+
</>
|
|
57
|
+
}
|
|
58
|
+
{`${value}%`}
|
|
59
|
+
</Body>
|
|
60
|
+
</div>
|
|
61
|
+
}
|
|
62
|
+
</>
|
|
63
|
+
)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export default StatChange
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { render, screen } from '../utilities/test-utils'
|
|
3
|
+
|
|
4
|
+
import StatChange from './_stat_change'
|
|
5
|
+
|
|
6
|
+
test('it renders each status', () => {
|
|
7
|
+
render(
|
|
8
|
+
<StatChange
|
|
9
|
+
change="increase"
|
|
10
|
+
value="28.4"
|
|
11
|
+
/>
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
const kit = screen.getByText('28.4%')
|
|
15
|
+
expect(kit).toHaveClass(`pb_body_kit_positive`)
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
test('it renders preset icon', () => {
|
|
19
|
+
render(
|
|
20
|
+
<StatChange
|
|
21
|
+
change="increase"
|
|
22
|
+
value="28.4"
|
|
23
|
+
/>
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
const kit = screen.getByLabelText('arrow-up icon')
|
|
27
|
+
expect(kit).toBeTruthy
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
test('it renders custom icon', () => {
|
|
31
|
+
render(
|
|
32
|
+
<StatChange
|
|
33
|
+
icon="chart-line-down"
|
|
34
|
+
value={6.1}
|
|
35
|
+
/>
|
|
36
|
+
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
const kit = screen.getByLabelText('chart-line-down icon')
|
|
40
|
+
expect(kit).toBeTruthy
|
|
41
|
+
})
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
/* @flow */
|
|
2
|
-
|
|
3
1
|
import React from 'react'
|
|
4
2
|
import classnames from 'classnames'
|
|
5
3
|
|
|
@@ -10,10 +8,10 @@ type StatValueProps = {
|
|
|
10
8
|
className?: string,
|
|
11
9
|
id?: string,
|
|
12
10
|
unit?: string,
|
|
13
|
-
value: string | number
|
|
11
|
+
value: string | number,
|
|
14
12
|
}
|
|
15
13
|
|
|
16
|
-
const StatValue = (props: StatValueProps) => {
|
|
14
|
+
const StatValue = (props: StatValueProps): React.ReactElement => {
|
|
17
15
|
const {
|
|
18
16
|
className,
|
|
19
17
|
id,
|
|
@@ -21,7 +19,7 @@ const StatValue = (props: StatValueProps) => {
|
|
|
21
19
|
value = 0,
|
|
22
20
|
} = props
|
|
23
21
|
|
|
24
|
-
const displayValue = function(value) {
|
|
22
|
+
const displayValue = function(value: string | number) {
|
|
25
23
|
if (value || value === 0) {
|
|
26
24
|
return (
|
|
27
25
|
<Title
|
|
@@ -33,7 +31,7 @@ const StatValue = (props: StatValueProps) => {
|
|
|
33
31
|
}
|
|
34
32
|
}
|
|
35
33
|
|
|
36
|
-
const displayUnit = function(unit) {
|
|
34
|
+
const displayUnit = function(unit: string) {
|
|
37
35
|
if (unit) {
|
|
38
36
|
return (
|
|
39
37
|
<Title
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { render, screen } from '../utilities/test-utils'
|
|
3
|
+
|
|
4
|
+
import StatValue from './_stat_value'
|
|
5
|
+
|
|
6
|
+
test('it renders the component with the value', () => {
|
|
7
|
+
render(
|
|
8
|
+
<StatValue
|
|
9
|
+
value={1048}
|
|
10
|
+
/>
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
const kit = screen.getByText('1048')
|
|
14
|
+
expect(kit).toBeTruthy()
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
test('it renders the component with the unit', () => {
|
|
18
|
+
render(
|
|
19
|
+
<StatValue
|
|
20
|
+
unit="appt"
|
|
21
|
+
value="5,294"
|
|
22
|
+
/>
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
const kit = screen.getByText('appt')
|
|
26
|
+
expect(kit).toBeTruthy()
|
|
27
|
+
})
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
/* @flow */
|
|
2
|
-
|
|
3
1
|
import React from 'react'
|
|
4
2
|
import classnames from 'classnames'
|
|
5
3
|
|
|
@@ -12,16 +10,16 @@ import Caption from '../pb_caption/_caption'
|
|
|
12
10
|
|
|
13
11
|
type TimeStackedProps = {
|
|
14
12
|
align?: 'left' | 'center' | 'right',
|
|
15
|
-
className?: string |
|
|
13
|
+
className?: string | string[],
|
|
16
14
|
dark?: boolean,
|
|
17
|
-
data?:
|
|
15
|
+
data?: { [key: string]: string },
|
|
18
16
|
date?: string,
|
|
19
17
|
id?: string,
|
|
20
18
|
time: number | Date,
|
|
21
19
|
timeZone?: string,
|
|
22
20
|
}
|
|
23
21
|
|
|
24
|
-
const TimeStackedDefault = (props: TimeStackedProps) => {
|
|
22
|
+
const TimeStackedDefault = (props: TimeStackedProps): React.ReactElement => {
|
|
25
23
|
if (props.date) deprecatedProps('Time Stacked', ['date']) //date prop is deprecated, use time instead
|
|
26
24
|
|
|
27
25
|
const {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { default as TimeStackedDefault } from './_time_stacked_default
|
|
1
|
+
export { default as TimeStackedDefault } from './_time_stacked_default'
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
/* @flow */
|
|
2
|
-
|
|
3
1
|
import React from 'react'
|
|
4
2
|
import classnames from 'classnames'
|
|
5
3
|
|
|
@@ -11,8 +9,8 @@ import Caption from '../pb_caption/_caption'
|
|
|
11
9
|
|
|
12
10
|
type TimestampProps = {
|
|
13
11
|
align?: "left" | "center" | "right",
|
|
14
|
-
aria?:
|
|
15
|
-
className?: string |
|
|
12
|
+
aria?: { [key: string]: string },
|
|
13
|
+
className?: string | string[],
|
|
16
14
|
dark?: boolean,
|
|
17
15
|
data?: string,
|
|
18
16
|
text: string,
|
|
@@ -26,7 +24,7 @@ type TimestampProps = {
|
|
|
26
24
|
variant?: "default" | "elapsed" | "updated"
|
|
27
25
|
}
|
|
28
26
|
|
|
29
|
-
const Timestamp = (props: TimestampProps) => {
|
|
27
|
+
const Timestamp = (props: TimestampProps): React.ReactElement => {
|
|
30
28
|
const {
|
|
31
29
|
align = 'left',
|
|
32
30
|
aria = {},
|
|
@@ -90,9 +88,9 @@ const Timestamp = (props: TimestampProps) => {
|
|
|
90
88
|
const captionText = () => {
|
|
91
89
|
switch (variant) {
|
|
92
90
|
case 'updated':
|
|
93
|
-
return formatUpdatedString(
|
|
91
|
+
return formatUpdatedString()
|
|
94
92
|
case 'elapsed':
|
|
95
|
-
return formatElapsedString(
|
|
93
|
+
return formatElapsedString()
|
|
96
94
|
default:
|
|
97
95
|
return showDate ? timestamp ? fullDateDisplay() : text : fullTimeDisplay()
|
|
98
96
|
}
|