playbook_ui 13.23.0.pre.alpha.PLAY1284investigation2657 β 13.24.0.pre.alpha.PBNTR261NewKitDropdown2681
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 +2 -0
- data/app/pb_kits/playbook/index.js +1 -0
- data/app/pb_kits/playbook/pb_bar_graph/_bar_graph.tsx +16 -2
- data/app/pb_kits/playbook/pb_bar_graph/bar_graph.rb +2 -0
- data/app/pb_kits/playbook/pb_bar_graph/docs/_bar_graph_negative_numbers.html.erb +23 -0
- data/app/pb_kits/playbook/pb_bar_graph/docs/_bar_graph_negative_numbers.jsx +35 -0
- data/app/pb_kits/playbook/pb_bar_graph/docs/_bar_graph_stacked.html.erb +22 -0
- data/app/pb_kits/playbook/pb_bar_graph/docs/_bar_graph_stacked.jsx +34 -0
- data/app/pb_kits/playbook/pb_bar_graph/docs/_bar_graph_stacked.md +1 -0
- data/app/pb_kits/playbook/pb_bar_graph/docs/example.yml +4 -0
- data/app/pb_kits/playbook/pb_bar_graph/docs/index.js +2 -0
- data/app/pb_kits/playbook/pb_dropdown/_dropdown.scss +92 -0
- data/app/pb_kits/playbook/pb_dropdown/_dropdown.tsx +152 -0
- data/app/pb_kits/playbook/pb_dropdown/context/index.tsx +5 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_default.jsx +53 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_display.jsx +104 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_options.jsx +69 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_trigger.jsx +78 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/example.yml +9 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/index.js +4 -0
- data/app/pb_kits/playbook/pb_dropdown/dropdown.test.jsx +17 -0
- data/app/pb_kits/playbook/pb_dropdown/hooks/useDropdown.tsx +17 -0
- data/app/pb_kits/playbook/pb_dropdown/hooks/useHandleOnKeydown.tsx +53 -0
- data/app/pb_kits/playbook/pb_dropdown/subcomponents/DropdownContainer.tsx +95 -0
- data/app/pb_kits/playbook/pb_dropdown/subcomponents/DropdownOption.tsx +91 -0
- data/app/pb_kits/playbook/pb_dropdown/subcomponents/DropdownTrigger.tsx +118 -0
- data/app/pb_kits/playbook/pb_list/_list_item.tsx +2 -2
- data/app/pb_kits/playbook/playbook-doc.js +2 -0
- data/app/pb_kits/playbook/tokens/_colors.scss +1 -1
- data/dist/menu.yml +5 -1
- data/dist/playbook-rails.js +6 -6
- data/lib/playbook/version.rb +2 -2
- metadata +22 -2
@@ -0,0 +1,69 @@
|
|
1
|
+
import React, { useState } from 'react'
|
2
|
+
import { Dropdown, Icon, Body, FlexItem, Flex } from '../..'
|
3
|
+
|
4
|
+
const DropdownWithCustomOptions = (props) => {
|
5
|
+
// eslint-disable-next-line no-unused-vars
|
6
|
+
const [selectedOption, setSelectedOption] = useState();
|
7
|
+
|
8
|
+
const options = [
|
9
|
+
{
|
10
|
+
label: "United States",
|
11
|
+
value: "United States",
|
12
|
+
areaCode: "+1",
|
13
|
+
icon: "πΊπΈ",
|
14
|
+
id: "United-states"
|
15
|
+
},
|
16
|
+
{
|
17
|
+
label: "Ukraine",
|
18
|
+
value: "Ukraine",
|
19
|
+
areaCode: "+380",
|
20
|
+
icon: "πΊπ¦",
|
21
|
+
id: "ukraine"
|
22
|
+
},
|
23
|
+
{
|
24
|
+
label: "Pakistan",
|
25
|
+
value: "Pakistan",
|
26
|
+
areaCode: "+92",
|
27
|
+
icon: "π΅π°",
|
28
|
+
id: "pakistan"
|
29
|
+
}
|
30
|
+
];
|
31
|
+
|
32
|
+
|
33
|
+
return (
|
34
|
+
<div>
|
35
|
+
<Dropdown
|
36
|
+
onSelect={(selectedItem) => setSelectedOption(selectedItem)}
|
37
|
+
options={options}
|
38
|
+
{...props}
|
39
|
+
>
|
40
|
+
<Dropdown.Trigger/>
|
41
|
+
<Dropdown.Container>
|
42
|
+
{options.map((option) => (
|
43
|
+
<Dropdown.Option key={option.id}
|
44
|
+
option={option}
|
45
|
+
>
|
46
|
+
<>
|
47
|
+
<FlexItem>
|
48
|
+
<Flex>
|
49
|
+
<Icon icon={option.icon}
|
50
|
+
paddingRight="xs"
|
51
|
+
/>
|
52
|
+
<Body text={option.label} />
|
53
|
+
</Flex>
|
54
|
+
</FlexItem>
|
55
|
+
<FlexItem>
|
56
|
+
<Body color="light"
|
57
|
+
text={option.areaCode}
|
58
|
+
/>
|
59
|
+
</FlexItem>
|
60
|
+
</>
|
61
|
+
</Dropdown.Option>
|
62
|
+
))}
|
63
|
+
</Dropdown.Container>
|
64
|
+
</Dropdown>
|
65
|
+
</div>
|
66
|
+
)
|
67
|
+
}
|
68
|
+
|
69
|
+
export default DropdownWithCustomOptions
|
@@ -0,0 +1,78 @@
|
|
1
|
+
import React, { useState } from 'react'
|
2
|
+
import { Dropdown, Icon, Body, FlexItem, Flex, IconCircle } from '../..'
|
3
|
+
|
4
|
+
const DropdownWithCustomTrigger = (props) => {
|
5
|
+
|
6
|
+
const [selectedOption, setSelectedOption] = useState();
|
7
|
+
|
8
|
+
const options = [
|
9
|
+
{
|
10
|
+
label: "United States",
|
11
|
+
value: "United States",
|
12
|
+
areaCode: "+1",
|
13
|
+
icon: "πΊπΈ",
|
14
|
+
id: "United-states"
|
15
|
+
},
|
16
|
+
{
|
17
|
+
label: "Ukraine",
|
18
|
+
value: "Ukraine",
|
19
|
+
areaCode: "+380",
|
20
|
+
icon: "πΊπ¦",
|
21
|
+
id: "ukraine"
|
22
|
+
},
|
23
|
+
{
|
24
|
+
label: "Pakistan",
|
25
|
+
value: "Pakistan",
|
26
|
+
areaCode: "+92",
|
27
|
+
icon: "π΅π°",
|
28
|
+
id: "pakistan"
|
29
|
+
}
|
30
|
+
];
|
31
|
+
|
32
|
+
|
33
|
+
return (
|
34
|
+
<div>
|
35
|
+
<Dropdown
|
36
|
+
onSelect={(selectedItem) => setSelectedOption(selectedItem)}
|
37
|
+
options={options}
|
38
|
+
{...props}
|
39
|
+
>
|
40
|
+
<Dropdown.Trigger>
|
41
|
+
<div key={selectedOption ? selectedOption.icon : "flag"}>
|
42
|
+
<IconCircle
|
43
|
+
cursor="pointer"
|
44
|
+
icon={selectedOption ? selectedOption.icon : "flag"}
|
45
|
+
variant="royal"
|
46
|
+
/>
|
47
|
+
</div>
|
48
|
+
</Dropdown.Trigger>
|
49
|
+
|
50
|
+
<Dropdown.Container>
|
51
|
+
{options.map((option) => (
|
52
|
+
<Dropdown.Option key={option.id}
|
53
|
+
option={option}
|
54
|
+
>
|
55
|
+
<>
|
56
|
+
<FlexItem>
|
57
|
+
<Flex>
|
58
|
+
<Icon icon={option.icon}
|
59
|
+
paddingRight="xs"
|
60
|
+
/>
|
61
|
+
<Body text={option.label} />
|
62
|
+
</Flex>
|
63
|
+
</FlexItem>
|
64
|
+
<FlexItem>
|
65
|
+
<Body color="light"
|
66
|
+
text={option.areaCode}
|
67
|
+
/>
|
68
|
+
</FlexItem>
|
69
|
+
</>
|
70
|
+
</Dropdown.Option>
|
71
|
+
))}
|
72
|
+
</Dropdown.Container>
|
73
|
+
</Dropdown>
|
74
|
+
</div>
|
75
|
+
)
|
76
|
+
}
|
77
|
+
|
78
|
+
export default DropdownWithCustomTrigger
|
@@ -0,0 +1,4 @@
|
|
1
|
+
export { default as DropdownDefault } from './_dropdown_default.jsx'
|
2
|
+
export { default as DropdownWithCustomDisplay } from './_dropdown_with_custom_display.jsx'
|
3
|
+
export { default as DropdownWithCustomOptions } from './_dropdown_with_custom_options.jsx'
|
4
|
+
export { default as DropdownWithCustomTrigger } from './_dropdown_with_custom_trigger.jsx'
|
@@ -0,0 +1,17 @@
|
|
1
|
+
import { renderKit } from '../utilities/test-utils'
|
2
|
+
|
3
|
+
import { Dropdown } 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(Dropdown , props)
|
16
|
+
expect(kit).toBeInTheDocument()
|
17
|
+
})
|
@@ -0,0 +1,17 @@
|
|
1
|
+
import {useState} from 'react';
|
2
|
+
|
3
|
+
|
4
|
+
const useDropdown = (initial=true) => {
|
5
|
+
|
6
|
+
const [isDropDownClosed, setIsDropDownClosed] = useState(initial);
|
7
|
+
|
8
|
+
const toggleDropdown = () => setIsDropDownClosed(!isDropDownClosed);
|
9
|
+
|
10
|
+
return [
|
11
|
+
isDropDownClosed,
|
12
|
+
setIsDropDownClosed as any,
|
13
|
+
toggleDropdown
|
14
|
+
]
|
15
|
+
}
|
16
|
+
|
17
|
+
export default useDropdown
|
@@ -0,0 +1,53 @@
|
|
1
|
+
import React, { useContext } from "react";
|
2
|
+
import DropdownContext from "../context";
|
3
|
+
|
4
|
+
|
5
|
+
export const useHandleOnKeyDown = () => {
|
6
|
+
|
7
|
+
const {
|
8
|
+
focusedOptionIndex,
|
9
|
+
filteredOptions,
|
10
|
+
setFocusedOptionIndex,
|
11
|
+
handleOptionClick,
|
12
|
+
setIsDropDownClosed,
|
13
|
+
handleBackspace,
|
14
|
+
selected
|
15
|
+
}= useContext(DropdownContext)
|
16
|
+
|
17
|
+
return (e: React.KeyboardEvent) => {
|
18
|
+
switch (e.key) {
|
19
|
+
case "Backspace":
|
20
|
+
case "Delete":
|
21
|
+
handleBackspace();
|
22
|
+
break;
|
23
|
+
case "ArrowDown": {
|
24
|
+
e.preventDefault();
|
25
|
+
setIsDropDownClosed(false);
|
26
|
+
const nextIndex = (focusedOptionIndex + 1) % filteredOptions.length;
|
27
|
+
setFocusedOptionIndex(nextIndex);
|
28
|
+
break;
|
29
|
+
}
|
30
|
+
case "ArrowUp": {
|
31
|
+
e.preventDefault();
|
32
|
+
const nextIndexUp =
|
33
|
+
(focusedOptionIndex - 1 + filteredOptions.length) %
|
34
|
+
filteredOptions.length;
|
35
|
+
setFocusedOptionIndex(nextIndexUp);
|
36
|
+
break;
|
37
|
+
}
|
38
|
+
case "Enter":
|
39
|
+
if (focusedOptionIndex !== -1) {
|
40
|
+
e.preventDefault();
|
41
|
+
handleOptionClick(filteredOptions[focusedOptionIndex]);
|
42
|
+
setFocusedOptionIndex(-1)
|
43
|
+
}
|
44
|
+
break;
|
45
|
+
default:
|
46
|
+
if (selected && selected.label) {
|
47
|
+
e.preventDefault();
|
48
|
+
handleBackspace();
|
49
|
+
}
|
50
|
+
break;
|
51
|
+
}
|
52
|
+
}
|
53
|
+
};
|
@@ -0,0 +1,95 @@
|
|
1
|
+
import React, { useContext } from "react";
|
2
|
+
import classnames from "classnames";
|
3
|
+
import {
|
4
|
+
buildAriaProps,
|
5
|
+
buildCss,
|
6
|
+
buildDataProps,
|
7
|
+
} from "../../utilities/props";
|
8
|
+
import { globalProps } from "../../utilities/globalProps";
|
9
|
+
|
10
|
+
import DropdownContext from "../context";
|
11
|
+
|
12
|
+
import List from "../../pb_list/_list";
|
13
|
+
import ListItem from "../../pb_list/_list_item";
|
14
|
+
import TextInput from "../../pb_text_input/_text_input";
|
15
|
+
import Body from "../../pb_body/_body";
|
16
|
+
|
17
|
+
type DropdownContainerProps = {
|
18
|
+
aria?: { [key: string]: string };
|
19
|
+
className?: string;
|
20
|
+
children?: React.ReactChild[] | React.ReactChild;
|
21
|
+
data?: { [key: string]: string };
|
22
|
+
id?: string;
|
23
|
+
searchbar?: boolean;
|
24
|
+
};
|
25
|
+
|
26
|
+
const DropdownContainer = (props: DropdownContainerProps) => {
|
27
|
+
const {
|
28
|
+
aria = {},
|
29
|
+
className,
|
30
|
+
children,
|
31
|
+
data = {},
|
32
|
+
id,
|
33
|
+
searchbar = false,
|
34
|
+
} = props;
|
35
|
+
|
36
|
+
const {
|
37
|
+
isDropDownClosed,
|
38
|
+
handleChange,
|
39
|
+
filterItem,
|
40
|
+
filteredOptions,
|
41
|
+
inputRef,
|
42
|
+
setFocusedOptionIndex,
|
43
|
+
} = useContext(DropdownContext);
|
44
|
+
|
45
|
+
const ariaProps = buildAriaProps(aria);
|
46
|
+
const dataProps = buildDataProps(data);
|
47
|
+
const classes = classnames(
|
48
|
+
buildCss("pb_dropdown_container"),
|
49
|
+
`${isDropDownClosed ? "close" : "open"}`,
|
50
|
+
globalProps(props),
|
51
|
+
className
|
52
|
+
);
|
53
|
+
|
54
|
+
return (
|
55
|
+
<div {...ariaProps}
|
56
|
+
{...dataProps}
|
57
|
+
className={classes}
|
58
|
+
id={id}
|
59
|
+
onMouseEnter={() => setFocusedOptionIndex(-1)}
|
60
|
+
>
|
61
|
+
{searchbar && (
|
62
|
+
<TextInput paddingTop="xs"
|
63
|
+
paddingX="xs"
|
64
|
+
>
|
65
|
+
<input
|
66
|
+
onChange={handleChange}
|
67
|
+
placeholder="Select..."
|
68
|
+
ref={inputRef}
|
69
|
+
value={filterItem}
|
70
|
+
/>
|
71
|
+
</TextInput>
|
72
|
+
)}
|
73
|
+
<List>{
|
74
|
+
filteredOptions?.length === 0 ? (
|
75
|
+
<ListItem
|
76
|
+
display="flex"
|
77
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
78
|
+
// @ts-ignore
|
79
|
+
justifyContent="center"
|
80
|
+
padding="xs"
|
81
|
+
>
|
82
|
+
<Body color="light"
|
83
|
+
text="no option"
|
84
|
+
/>
|
85
|
+
</ListItem>
|
86
|
+
): (
|
87
|
+
children
|
88
|
+
)
|
89
|
+
}
|
90
|
+
</List>
|
91
|
+
</div>
|
92
|
+
);
|
93
|
+
};
|
94
|
+
|
95
|
+
export default DropdownContainer;
|
@@ -0,0 +1,91 @@
|
|
1
|
+
import React, { useContext } from "react";
|
2
|
+
import classnames from "classnames";
|
3
|
+
import {
|
4
|
+
buildAriaProps,
|
5
|
+
buildCss,
|
6
|
+
buildDataProps,
|
7
|
+
} from "../../utilities/props";
|
8
|
+
import { globalProps } from "../../utilities/globalProps";
|
9
|
+
|
10
|
+
import DropdownContext from "../context";
|
11
|
+
|
12
|
+
import Flex from "../../pb_flex/_flex";
|
13
|
+
import Body from "../../pb_body/_body";
|
14
|
+
import ListItem from "../../pb_list/_list_item";
|
15
|
+
import { GenericObject } from "../../types";
|
16
|
+
|
17
|
+
type DropdownOptionProps = {
|
18
|
+
aria?: { [key: string]: string };
|
19
|
+
className?: string;
|
20
|
+
children?: React.ReactChild[] | React.ReactChild;
|
21
|
+
data?: { [key: string]: string };
|
22
|
+
id?: string;
|
23
|
+
option?: GenericObject;
|
24
|
+
key?: string;
|
25
|
+
};
|
26
|
+
|
27
|
+
const DropdownOption = (props: DropdownOptionProps) => {
|
28
|
+
const { aria = {}, className, children, data = {}, id, option, key } = props;
|
29
|
+
|
30
|
+
const { handleOptionClick, selected, filterItem, filteredOptions, focusedOptionIndex } =
|
31
|
+
useContext(DropdownContext);
|
32
|
+
|
33
|
+
const isItemMatchingFilter = (option: GenericObject) =>
|
34
|
+
option?.label.toLowerCase().includes(filterItem.toLowerCase());
|
35
|
+
|
36
|
+
if (!isItemMatchingFilter(option)) {
|
37
|
+
return null;
|
38
|
+
}
|
39
|
+
const isFocused = focusedOptionIndex >= 0 && filteredOptions[focusedOptionIndex].label === option.label
|
40
|
+
const focusedClass = isFocused && "dropdown_option_focused"
|
41
|
+
|
42
|
+
const selectedClass = `${
|
43
|
+
selected.label === option.label
|
44
|
+
? "dropdown_option_selected"
|
45
|
+
: "dropdown_option_list"
|
46
|
+
}`
|
47
|
+
const ariaProps = buildAriaProps(aria);
|
48
|
+
const dataProps = buildDataProps(data);
|
49
|
+
const classes = classnames(
|
50
|
+
buildCss("pb_dropdown_option"),
|
51
|
+
selectedClass,
|
52
|
+
focusedClass,
|
53
|
+
globalProps(props),
|
54
|
+
className
|
55
|
+
);
|
56
|
+
|
57
|
+
return (
|
58
|
+
<div {...ariaProps}
|
59
|
+
{...dataProps}
|
60
|
+
className={classes}
|
61
|
+
id={id}
|
62
|
+
key={key}
|
63
|
+
>
|
64
|
+
<ListItem
|
65
|
+
cursor="pointer"
|
66
|
+
data-name={option.value}
|
67
|
+
htmlOptions={{ onClick: () => handleOptionClick(option) }}
|
68
|
+
key={option.label}
|
69
|
+
padding="xs"
|
70
|
+
>
|
71
|
+
<Flex
|
72
|
+
align="center"
|
73
|
+
className="dropdown_option"
|
74
|
+
justify="between"
|
75
|
+
paddingX="sm"
|
76
|
+
paddingY="xxs"
|
77
|
+
>
|
78
|
+
{
|
79
|
+
children ? (
|
80
|
+
children
|
81
|
+
) : (
|
82
|
+
<Body text={option.label}/>
|
83
|
+
)
|
84
|
+
}
|
85
|
+
</Flex>
|
86
|
+
</ListItem>
|
87
|
+
</div>
|
88
|
+
);
|
89
|
+
};
|
90
|
+
|
91
|
+
export default DropdownOption;
|
@@ -0,0 +1,118 @@
|
|
1
|
+
import React, { useContext } from "react";
|
2
|
+
import classnames from "classnames";
|
3
|
+
import {
|
4
|
+
buildAriaProps,
|
5
|
+
buildCss,
|
6
|
+
buildDataProps,
|
7
|
+
} from "../../utilities/props";
|
8
|
+
import { globalProps } from "../../utilities/globalProps";
|
9
|
+
import { useHandleOnKeyDown } from "../hooks/useHandleOnKeydown";
|
10
|
+
|
11
|
+
import DropdownContext from "../context";
|
12
|
+
|
13
|
+
import Body from "../../pb_body/_body";
|
14
|
+
import Icon from "../../pb_icon/_icon";
|
15
|
+
import Flex from "../../pb_flex/_flex";
|
16
|
+
import FlexItem from "../../pb_flex/_flex_item";
|
17
|
+
|
18
|
+
type DropdownTriggerProps = {
|
19
|
+
aria?: { [key: string]: string };
|
20
|
+
children?: React.ReactChild[] | React.ReactChild;
|
21
|
+
className?: string;
|
22
|
+
customDisplay?: React.ReactChild[] | React.ReactChild;
|
23
|
+
data?: { [key: string]: string };
|
24
|
+
id?: string;
|
25
|
+
};
|
26
|
+
|
27
|
+
const DropdownTrigger = (props: DropdownTriggerProps) => {
|
28
|
+
const { aria = {}, className, children, customDisplay, data = {}, id } = props;
|
29
|
+
|
30
|
+
const {
|
31
|
+
handleWrapperClick,
|
32
|
+
selected,
|
33
|
+
filterItem,
|
34
|
+
handleChange,
|
35
|
+
toggleDropdown,
|
36
|
+
isDropDownClosed,
|
37
|
+
inputRef,
|
38
|
+
isInputFocused,
|
39
|
+
setIsInputFocused
|
40
|
+
} = useContext(DropdownContext);
|
41
|
+
|
42
|
+
const handleKeyDown = useHandleOnKeyDown();
|
43
|
+
|
44
|
+
const ariaProps = buildAriaProps(aria);
|
45
|
+
const dataProps = buildDataProps(data);
|
46
|
+
const classes = classnames(
|
47
|
+
buildCss("pb_dropdown_trigger"),
|
48
|
+
globalProps(props),
|
49
|
+
className
|
50
|
+
);
|
51
|
+
|
52
|
+
return (
|
53
|
+
<div {...ariaProps}
|
54
|
+
{...dataProps}
|
55
|
+
className={classes}
|
56
|
+
id={id}
|
57
|
+
>
|
58
|
+
{children ? (
|
59
|
+
<div
|
60
|
+
onClick={() => toggleDropdown()}
|
61
|
+
style={{ display: "inline-block" }}
|
62
|
+
>
|
63
|
+
{children}
|
64
|
+
</div>
|
65
|
+
) : (
|
66
|
+
<>
|
67
|
+
<Flex align="center"
|
68
|
+
borderRadius="lg"
|
69
|
+
className={`dropdown_trigger_wrapper ${isInputFocused && 'dropdown_trigger_wrapper_focus'}`}
|
70
|
+
cursor="text"
|
71
|
+
htmlOptions={{ onClick: () => handleWrapperClick(), tabIndex:"0" }}
|
72
|
+
justify="between"
|
73
|
+
paddingX="sm"
|
74
|
+
paddingY="xs"
|
75
|
+
>
|
76
|
+
<FlexItem>
|
77
|
+
<Flex align="center">
|
78
|
+
{customDisplay ? (
|
79
|
+
<Flex align="center">
|
80
|
+
{customDisplay}
|
81
|
+
<Body paddingLeft="xs">
|
82
|
+
<b>{selected.label}</b>
|
83
|
+
</Body>
|
84
|
+
</Flex>
|
85
|
+
) : (
|
86
|
+
selected.label && <Body text={selected.label} />
|
87
|
+
)
|
88
|
+
}
|
89
|
+
<input
|
90
|
+
className="dropdown_input"
|
91
|
+
onChange={handleChange}
|
92
|
+
onClick={() => toggleDropdown()}
|
93
|
+
onFocus={() => setIsInputFocused(true)}
|
94
|
+
onKeyDown={handleKeyDown}
|
95
|
+
placeholder={selected.label ? "" : "Select..."}
|
96
|
+
ref={inputRef}
|
97
|
+
value={filterItem}
|
98
|
+
/>
|
99
|
+
</Flex>
|
100
|
+
</FlexItem>
|
101
|
+
<FlexItem>
|
102
|
+
<Body color="light"
|
103
|
+
key={`${isDropDownClosed ? "chevron-down" : 'chevron-up'}`}
|
104
|
+
>
|
105
|
+
<Icon cursor="pointer"
|
106
|
+
icon={`${isDropDownClosed ? "chevron-down" : 'chevron-up'}`}
|
107
|
+
size="sm"
|
108
|
+
/>
|
109
|
+
</Body>
|
110
|
+
</FlexItem>
|
111
|
+
</Flex>
|
112
|
+
</>
|
113
|
+
)}
|
114
|
+
</div>
|
115
|
+
);
|
116
|
+
};
|
117
|
+
|
118
|
+
export default DropdownTrigger;
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import React from 'react'
|
2
2
|
import classnames from 'classnames'
|
3
3
|
import { buildAriaProps, buildCss, buildDataProps, buildHtmlProps } from '../utilities/props'
|
4
|
-
import { globalProps } from '../utilities/globalProps'
|
4
|
+
import { globalProps, GlobalProps } from '../utilities/globalProps'
|
5
5
|
|
6
6
|
type ListItemProps = {
|
7
7
|
aria?: { [key: string]: string },
|
@@ -11,7 +11,7 @@ type ListItemProps = {
|
|
11
11
|
htmlOptions?: {[key: string]: string | number | boolean | (() => void)},
|
12
12
|
id?: string,
|
13
13
|
tabIndex?: number,
|
14
|
-
}
|
14
|
+
} & GlobalProps
|
15
15
|
|
16
16
|
const ListItem = (props: ListItemProps) => {
|
17
17
|
const {
|
@@ -34,6 +34,7 @@ import * as DateYearStacked from 'pb_date_year_stacked/docs'
|
|
34
34
|
import * as Detail from 'pb_detail/docs'
|
35
35
|
import * as Dialog from 'pb_dialog/docs'
|
36
36
|
import * as DistributionBarDocs from 'pb_distribution_bar/docs'
|
37
|
+
import * as Dropdown from 'pb_dropdown/docs'
|
37
38
|
import * as FileUpload from 'pb_file_upload/docs'
|
38
39
|
import * as Filter from 'pb_filter/docs'
|
39
40
|
import * as FixedConfirmationToast from 'pb_fixed_confirmation_toast/docs'
|
@@ -136,6 +137,7 @@ WebpackerReact.registerComponents({
|
|
136
137
|
...Detail,
|
137
138
|
...Dialog,
|
138
139
|
...DistributionBarDocs,
|
140
|
+
...Dropdown,
|
139
141
|
...FileUpload,
|
140
142
|
...Filter,
|
141
143
|
...FixedConfirmationToast,
|
data/dist/menu.yml
CHANGED
@@ -254,6 +254,10 @@ kits:
|
|
254
254
|
platforms: *web
|
255
255
|
description: Playbook's date picker is built using flatpickr, a vanilla js library. Common date picker use cases and features have been adapted into simple prop based configuration detailed in the docs below.
|
256
256
|
status: "stable"
|
257
|
+
- name: dropdown
|
258
|
+
platforms: *react_only
|
259
|
+
description: ""
|
260
|
+
status: "beta"
|
257
261
|
- name: "multi_level_select"
|
258
262
|
platforms: *web
|
259
263
|
description: The MultiLevelSelect kit renders a multi leveled select dropdown based on data from the user.
|
@@ -460,4 +464,4 @@ kits:
|
|
460
464
|
- name: "user"
|
461
465
|
platforms: *web
|
462
466
|
description: This kit was created for having a systematic way of displaying users with avatar, titles, name and territory. This is a versatile kit with features than can be added to display more info.
|
463
|
-
status: "stable"
|
467
|
+
status: "stable"
|