playbook_ui 12.2.0 → 12.3.0.pre.alpha.patchtest1
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 +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_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_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_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 +3 -1
- data/app/pb_kits/playbook/utilities/_focus.scss +12 -0
- data/lib/playbook/version.rb +2 -2
- metadata +20 -5
@@ -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;
|
@@ -18,7 +18,7 @@ import Option from './components/Option'
|
|
18
18
|
import Placeholder from './components/Placeholder'
|
19
19
|
import ValueContainer from './components/ValueContainer'
|
20
20
|
|
21
|
-
import { noop } from '../utilities/props'
|
21
|
+
import { noop, buildDataProps } from '../utilities/props'
|
22
22
|
|
23
23
|
/**
|
24
24
|
* @typedef {object} Props
|
@@ -32,6 +32,8 @@ type TypeaheadProps = {
|
|
32
32
|
components?: object,
|
33
33
|
createable?: boolean,
|
34
34
|
dark?: boolean,
|
35
|
+
data?: object,
|
36
|
+
error?: string,
|
35
37
|
id?: string,
|
36
38
|
label?: string,
|
37
39
|
loadOptions?: string,
|
@@ -49,6 +51,8 @@ const Typeahead = ({
|
|
49
51
|
async,
|
50
52
|
components = {},
|
51
53
|
createable,
|
54
|
+
error = "",
|
55
|
+
data = {},
|
52
56
|
getOptionLabel,
|
53
57
|
getOptionValue,
|
54
58
|
id,
|
@@ -106,13 +110,18 @@ const Typeahead = ({
|
|
106
110
|
}
|
107
111
|
}
|
108
112
|
|
113
|
+
const dataProps = buildDataProps(data)
|
114
|
+
|
109
115
|
const classes = `pb_typeahead_kit react-select ${globalProps(props)}`
|
110
116
|
const inlineClass = selectProps.inline ? 'inline' : null
|
111
117
|
|
112
118
|
return (
|
113
|
-
<div
|
119
|
+
<div {...dataProps}
|
120
|
+
className={classnames(classes, inlineClass)}
|
121
|
+
>
|
114
122
|
<Tag
|
115
123
|
classNamePrefix="typeahead-kit-select"
|
124
|
+
error={error}
|
116
125
|
onChange={handleOnChange}
|
117
126
|
{...selectProps}
|
118
127
|
/>
|
@@ -0,0 +1,95 @@
|
|
1
|
+
import React from 'react'
|
2
|
+
import { render, screen } from '../utilities/test-utils'
|
3
|
+
import Typeahead from './_typeahead'
|
4
|
+
|
5
|
+
const options = [
|
6
|
+
{ label: 'Orange', value: '#FFA500' },
|
7
|
+
{ label: 'Red', value: '#FF0000' },
|
8
|
+
{ label: 'Green', value: '#00FF00' },
|
9
|
+
{ label: 'Blue', value: '#0000FF' },
|
10
|
+
]
|
11
|
+
|
12
|
+
test('typeahead classname + label renders as expected', () => {
|
13
|
+
render(
|
14
|
+
<Typeahead
|
15
|
+
data={{ testid: 'typeahead-test' }}
|
16
|
+
defaultValue={[options[0]]}
|
17
|
+
label="Colors"
|
18
|
+
options={options}
|
19
|
+
/>
|
20
|
+
)
|
21
|
+
|
22
|
+
const kit = screen.getByTestId('typeahead-test')
|
23
|
+
const label = kit.querySelector(".pb_caption_kit_md.pb_text_input_kit_label")
|
24
|
+
expect(kit).toHaveClass("pb_typeahead_kit")
|
25
|
+
expect(label).toHaveTextContent("Colors")
|
26
|
+
})
|
27
|
+
|
28
|
+
test('to be error variant', () => {
|
29
|
+
render(
|
30
|
+
<Typeahead
|
31
|
+
data={{ testid: 'error-test' }}
|
32
|
+
error='Please make a valid selection'
|
33
|
+
options={options}
|
34
|
+
/>
|
35
|
+
)
|
36
|
+
|
37
|
+
const kit = screen.getByTestId("error-test")
|
38
|
+
const error = kit.querySelector(".pb_body_kit_negative")
|
39
|
+
expect(error).toBeInTheDocument()
|
40
|
+
})
|
41
|
+
|
42
|
+
test('should be inline variant', () => {
|
43
|
+
render(
|
44
|
+
<Typeahead
|
45
|
+
data={{ testid: 'inline-test' }}
|
46
|
+
inline
|
47
|
+
options={options}
|
48
|
+
/>
|
49
|
+
)
|
50
|
+
|
51
|
+
const kit = screen.getByTestId('inline-test')
|
52
|
+
expect(kit).toHaveClass("inline")
|
53
|
+
})
|
54
|
+
|
55
|
+
test('typeahead with pills', () => {
|
56
|
+
render(
|
57
|
+
<Typeahead
|
58
|
+
data={{ testid: 'pills-test' }}
|
59
|
+
defaultValue={[options[0]]}
|
60
|
+
isMulti
|
61
|
+
options={options}
|
62
|
+
/>
|
63
|
+
)
|
64
|
+
|
65
|
+
const kit = screen.getByTestId('pills-test')
|
66
|
+
const pill = kit.querySelector(".pb_form_pill_kit_primary")
|
67
|
+
expect(pill).toBeInTheDocument()
|
68
|
+
})
|
69
|
+
|
70
|
+
test('typeahead multi select with badges and small pills', () => {
|
71
|
+
render(
|
72
|
+
<>
|
73
|
+
<Typeahead
|
74
|
+
data={{ testid: 'badge-test' }}
|
75
|
+
defaultValue={[options[0]]}
|
76
|
+
isMulti
|
77
|
+
multiKit="badge"
|
78
|
+
options={options}
|
79
|
+
/>
|
80
|
+
|
81
|
+
<Typeahead
|
82
|
+
data={{ testid: 'small-pill-test' }}
|
83
|
+
defaultValue={[options[0]]}
|
84
|
+
isMulti
|
85
|
+
multiKit="smallPill"
|
86
|
+
options={options}
|
87
|
+
/>
|
88
|
+
</>
|
89
|
+
)
|
90
|
+
|
91
|
+
const kit = screen.getByTestId('small-pill-test')
|
92
|
+
const badge = kit.querySelector(".pb_form_pill_kit_primary.mr_xs.small")
|
93
|
+
expect(badge).toBeInTheDocument()
|
94
|
+
})
|
95
|
+
|
@@ -0,0 +1,19 @@
|
|
1
|
+
<%
|
2
|
+
options = [
|
3
|
+
{ label: 'Windows', value: '#FFA500' },
|
4
|
+
{ label: 'Siding', value: '#FF0000' },
|
5
|
+
{ label: 'Doors', value: '#00FF00' },
|
6
|
+
{ label: 'Roofs', value: '#0000FF' },
|
7
|
+
]
|
8
|
+
|
9
|
+
%>
|
10
|
+
|
11
|
+
<%= pb_rails("typeahead", props: { id: "typeahead-error-example", options: options, error: "Please make a valid selection", label: "Products", name: :foo, is_multi: false }) %>
|
12
|
+
|
13
|
+
<!-- This section is an example of the available JavaScript event hooks -->
|
14
|
+
<%= javascript_tag defer: "defer" do %>
|
15
|
+
document.addEventListener("pb-typeahead-kit-typeahead-error-example-result-option-select", function(event) {
|
16
|
+
console.log('Option selected')
|
17
|
+
console.dir(event.detail)
|
18
|
+
})
|
19
|
+
<% end %>
|
@@ -0,0 +1,39 @@
|
|
1
|
+
// @flow
|
2
|
+
|
3
|
+
import React, { useState, useEffect } from 'react'
|
4
|
+
|
5
|
+
import Typeahead from '../_typeahead'
|
6
|
+
|
7
|
+
const options = [
|
8
|
+
{ label: 'Orange', value: '#FFA500' },
|
9
|
+
{ label: 'Red', value: '#FF0000' },
|
10
|
+
{ label: 'Green', value: '#00FF00' },
|
11
|
+
{ label: 'Blue', value: '#0000FF' },
|
12
|
+
]
|
13
|
+
|
14
|
+
const TypeaheadErrorState = (props) => {
|
15
|
+
const [errorState, setErrorState] = useState("Please make a valid selection");
|
16
|
+
const [searchValue, setSearchValue] = useState(null);
|
17
|
+
|
18
|
+
const handleOnChange = (value) => setSearchValue(value)
|
19
|
+
|
20
|
+
useEffect(() => {
|
21
|
+
if(searchValue) {
|
22
|
+
setErrorState("")
|
23
|
+
} else {
|
24
|
+
setErrorState("Please make a valid selection")
|
25
|
+
}
|
26
|
+
}, [searchValue])
|
27
|
+
|
28
|
+
return (
|
29
|
+
<Typeahead
|
30
|
+
error={errorState}
|
31
|
+
label="Colors"
|
32
|
+
onChange={handleOnChange}
|
33
|
+
options={options}
|
34
|
+
{...props}
|
35
|
+
/>
|
36
|
+
)
|
37
|
+
}
|
38
|
+
|
39
|
+
export default TypeaheadErrorState
|
@@ -0,0 +1 @@
|
|
1
|
+
Typeahead w/ Error shows that an option must be selected or the selected option is invalid (i.e., when used in a form it signals a user to fix an error).
|
@@ -8,6 +8,7 @@ examples:
|
|
8
8
|
- typeahead_with_pills_async_users: With Pills (Async Data w/ Users)
|
9
9
|
- typeahead_inline: Inline
|
10
10
|
- typeahead_multi_kit: Multi Kit Options
|
11
|
+
- typeahead_error_state: Error State
|
11
12
|
|
12
13
|
react:
|
13
14
|
- typeahead_default: Default
|
@@ -20,3 +21,4 @@ examples:
|
|
20
21
|
- typeahead_multi_kit: Multi Kit Options
|
21
22
|
- typeahead_createable: Createable
|
22
23
|
- typeahead_async_createable: Createable (+ Async Data)
|
24
|
+
- typeahead_error_state: Error State
|
@@ -8,3 +8,4 @@ export { default as TypeaheadInline } from './_typeahead_inline.jsx'
|
|
8
8
|
export { default as TypeaheadMultiKit } from './_typeahead_multi_kit.jsx'
|
9
9
|
export { default as TypeaheadCreateable } from './_typeahead_createable.jsx'
|
10
10
|
export { default as TypeaheadAsyncCreateable } from './_typeahead_async_createable.jsx'
|
11
|
+
export { default as TypeaheadErrorState } from './_typeahead_error_state.jsx'
|
@@ -5,6 +5,8 @@ module Playbook
|
|
5
5
|
class Typeahead < Playbook::KitBase
|
6
6
|
prop :async, type: Playbook::Props::Boolean, default: false
|
7
7
|
prop :default_options, type: Playbook::Props::HashArray, default: []
|
8
|
+
prop :error, type: Playbook::Props::String,
|
9
|
+
default: ""
|
8
10
|
prop :get_option_label
|
9
11
|
prop :get_option_value
|
10
12
|
prop :id
|
@@ -57,6 +59,7 @@ module Playbook
|
|
57
59
|
base_options = {
|
58
60
|
dark: dark,
|
59
61
|
defaultValue: default_options,
|
62
|
+
error: error,
|
60
63
|
id: id,
|
61
64
|
inline: inline,
|
62
65
|
isMulti: is_multi,
|
@@ -55,6 +55,7 @@ import * as Lightbox from 'pb_lightbox/docs'
|
|
55
55
|
import * as LineGraphDocs from 'pb_line_graph/docs'
|
56
56
|
import * as List from 'pb_list/docs'
|
57
57
|
import * as LoadingInline from 'pb_loading_inline/docs'
|
58
|
+
import * as Map from 'pb_map/docs'
|
58
59
|
import * as Message from 'pb_message/docs'
|
59
60
|
import * as MultipleUsers from 'pb_multiple_users/docs'
|
60
61
|
import * as MultipleUsersStacked from 'pb_multiple_users_stacked/docs'
|
@@ -152,6 +153,7 @@ WebpackerReact.setup({
|
|
152
153
|
...LineGraphDocs,
|
153
154
|
...List,
|
154
155
|
...LoadingInline,
|
156
|
+
...Map,
|
155
157
|
...Message,
|
156
158
|
...MultipleUsers,
|
157
159
|
...MultipleUsersStacked,
|
@@ -96,11 +96,13 @@ $hover_colors: (
|
|
96
96
|
);
|
97
97
|
|
98
98
|
/* Focus colors -----------------------*/
|
99
|
+
$focus_color: $primary;
|
99
100
|
$focus_input_light: rgba($active_light, $opacity_5);
|
100
101
|
$focus_input_dark: rgba(#144075, $opacity_5);
|
101
102
|
$focus_input_colors: (
|
102
103
|
focus_input_light: $focus_input_light,
|
103
|
-
focus_input_dark: $focus_input_dark
|
104
|
+
focus_input_dark: $focus_input_dark,
|
105
|
+
focus_color: $focus_color
|
104
106
|
);
|
105
107
|
|
106
108
|
/* Border colors ----------------------*/
|