playbook_ui 13.25.0.pre.alpha.PBNTR272Dropdownkitv42769 β†’ 13.25.0.pre.alpha.PLAY1249fixTooltipswrappingformelementscausingmisalignment2783

Sign up to get free protection for your applications and to get access to all the features.
Files changed (27) hide show
  1. checksums.yaml +4 -4
  2. data/app/pb_kits/playbook/index.js +0 -1
  3. data/app/pb_kits/playbook/pb_dropdown/_dropdown.scss +12 -90
  4. data/app/pb_kits/playbook/pb_dropdown/_dropdown.tsx +11 -63
  5. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_default.jsx +13 -1
  6. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_default.md +0 -1
  7. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_display.jsx +1 -1
  8. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_display.md +1 -3
  9. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_options.jsx +4 -1
  10. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_padding.jsx +4 -1
  11. data/app/pb_kits/playbook/pb_dropdown/docs/example.yml +2 -5
  12. data/app/pb_kits/playbook/pb_dropdown/docs/index.js +1 -4
  13. data/app/pb_kits/playbook/pb_dropdown/dropdown.test.jsx +10 -200
  14. data/app/pb_kits/playbook/pb_dropdown/hooks/useDropdown.tsx +2 -2
  15. data/app/pb_kits/playbook/pb_dropdown/hooks/useHandleOnKeydown.tsx +4 -4
  16. data/app/pb_kits/playbook/pb_dropdown/subcomponents/DropdownContainer.tsx +8 -17
  17. data/app/pb_kits/playbook/pb_dropdown/subcomponents/DropdownOption.tsx +8 -16
  18. data/app/pb_kits/playbook/pb_dropdown/subcomponents/DropdownTrigger.tsx +78 -96
  19. data/app/pb_kits/playbook/pb_dropdown/utilities/subComponentHelper.tsx +7 -9
  20. data/app/pb_kits/playbook/pb_tooltip/_tooltip.tsx +0 -1
  21. data/dist/playbook-rails.js +4 -4
  22. data/lib/playbook/version.rb +1 -1
  23. metadata +2 -6
  24. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_external_control.jsx +0 -62
  25. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_hook.jsx +0 -75
  26. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_label.jsx +0 -39
  27. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_label.md +0 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 71177d67df222d53293af018a05b5a4aa6e8c2320e2666e4a0fa306f9c7fa6b6
4
- data.tar.gz: 4020bc3572296e4c84a58b117cd6b194d2875429baf2bcf606f5a9e2f3772b25
3
+ metadata.gz: 3421551f1607dca5e7327a0a79592d4159a3b09b51e58ee2ef5931e34d139899
4
+ data.tar.gz: 903d65b4681ad27ebb04e1395692b8194eaf04b7597f4fbe3a009e57c36f858f
5
5
  SHA512:
6
- metadata.gz: b628362eb09ed93b1084e3452766c4753edda243367d3217379e4ad4b83738567931f26af432583a7d38e34dcf8085c6ae05bb6415460a8cbf5b438a25ffd603
7
- data.tar.gz: 1aed46186c6455ad3e8adb45e63fe1a55358237eec9c2fd72db3b12a4a9cdbc7031099be20d38e2e79a9bedf89b74cb97a96ed4cc67b05649e5d682064bfade0
6
+ metadata.gz: ef84f9924ce1d67995432f1b8f5c04362f6d1f2fd1cfbc3ab36e20b34cd20fab37ef3bb28463939d6bbf3bad609a766064245b3af506888147b55f234d80fe1d
7
+ data.tar.gz: 9b0e28d7fe9c85e254222c57034af036e1fdd4868ca3596af0390aa61c5c92eb0d3c486b2c2825eb2d91a6eaf367d149d4d3fb64b49839edb11a8f6dd5bfe6a0
@@ -133,7 +133,6 @@ export { default as dialogHelper } from './pb_dialog/dialogHelper'
133
133
  //Theming
134
134
  export {default as mapTheme} from './pb_map/pbMapTheme'
135
135
  export {default as useCollapsible} from './pb_collapsible/useCollapsible'
136
- export {default as useDropdown } from './pb_dropdown/hooks/useDropdown'
137
136
 
138
137
  // CSS Tokens
139
138
  export { default as borderRadius } from './tokens/exports/_border_radius.scss'
@@ -5,30 +5,11 @@
5
5
  @import "../tokens/shadows";
6
6
  @import "../tokens/positioning";
7
7
  @import "../pb_body/body_mixins";
8
- @import "../pb_textarea/textarea_mixin";
9
-
10
- @keyframes fadeIn {
11
- from {
12
- opacity: 0;
13
- }
14
-
15
- to {
16
- opacity: 1;
17
- }
18
- }
19
- @keyframes fadeOut {
20
- from {
21
- opacity: 1;
22
- }
23
-
24
- to {
25
- opacity: 0;
26
- }
27
- }
28
8
 
29
9
  .pb_dropdown {
30
10
  .dropdown_wrapper {
31
- [class*=dropdown_trigger_wrapper] {
11
+ position: relative;
12
+ .dropdown_trigger_wrapper {
32
13
  @include pb_body;
33
14
  border: 1px solid $border_light;
34
15
  background-color: $white;
@@ -59,15 +40,15 @@
59
40
  outline: unset;
60
41
  transition: box-shadow 0.15s ease-in-out;
61
42
  }
62
-
63
- &[class*=_select_only] {
64
- box-shadow: inset 0 -11px 20px rgba($primary, 0.05);
65
- }
43
+ }
66
44
 
67
- &[class*=_focus] {
68
- box-shadow: 0px 0px 0 1px $primary;
69
- transition: box-shadow 0.1s ease-in-out;
70
- }
45
+ .dropdown_trigger_wrapper_select_only {
46
+ box-shadow: inset 0 -11px 20px rgba($primary, 0.05);
47
+ }
48
+
49
+ .dropdown_trigger_wrapper_focus {
50
+ box-shadow: 0px 0px 0 1px $primary;
51
+ transition: box-shadow 0.1s ease-in-out;
71
52
  }
72
53
 
73
54
  .pb_dropdown_container {
@@ -77,8 +58,10 @@
77
58
  border-radius: $border_rad_heavier;
78
59
  border: 1px solid $border_light;
79
60
  margin-top: $space_xs;
61
+ position: absolute;
80
62
  z-index: $z_1;
81
63
  width: 100%;
64
+ transition: opacity 0.25s ease-in-out;
82
65
 
83
66
  .pb_dropdown_option {
84
67
  cursor: pointer;
@@ -111,71 +94,10 @@
111
94
  }
112
95
  .close {
113
96
  display: none;
114
- animation-name: fadeOut;
115
- animation-duration: 150ms;
116
- animation-timing-function: linear;
117
- animation-fill-mode: forwards;
118
97
  }
119
98
 
120
99
  .open {
121
100
  display: block;
122
- animation-name: fadeIn;
123
- animation-duration: 150ms;
124
- animation-timing-function: linear;
125
- animation-fill-mode: forwards;
126
- }
127
- }
128
-
129
- &.dark {
130
- .dropdown_wrapper {
131
- [class*=dropdown_trigger_wrapper] {
132
- @include pb_body_light_dark;
133
- background-color: rgba($white, 0.1) !important;
134
- background: none;
135
- border-color: rgba($white, 0.15);
136
- @media (hover: hover) {
137
- &:hover,
138
- &:active,
139
- &:focus {
140
- background-color: rgba($white, 0.05) !important;
141
- }
142
- }
143
- [class^="pb_body"] {
144
- color: $white;
145
- }
146
- &[class*=_select_only] {
147
- box-shadow: inset 0 -11px 20px rgba($white, 0.05) !important;
148
- }
149
-
150
- .dropdown_input {
151
- background-color: unset;
152
- color: $white;
153
- }
154
- }
155
- }
156
- .pb_dropdown_container {
157
- background-color: $bg_dark !important;
158
- border-color: rgba($white, 0.15);
159
- color: $white;
160
- .dropdown_option_list {
161
- border-color: rgba($white, 0.15);
162
- }
163
- [class^="pb_body"],
164
- [class^="pb_title_kit"] {
165
- color: $white !important;
166
- }
167
-
168
- .pb_dropdown_option {
169
- &:hover {
170
- background-color: $hover_dark;
171
- }
172
- }
173
- .dropdown_option_focused {
174
- background-color: $hover_dark;
175
- }
176
- .dropdown_option_selected {
177
- background-color: $primary;
178
- }
179
101
  }
180
102
  }
181
103
  }
@@ -4,7 +4,6 @@ import { buildAriaProps, buildCss, buildDataProps, buildHtmlProps } from "../uti
4
4
  import { globalProps } from "../utilities/globalProps";
5
5
 
6
6
  import Body from "../pb_body/_body";
7
- import Caption from "../pb_caption/_caption";
8
7
 
9
8
  import DropdownContainer from "./subcomponents/DropdownContainer";
10
9
  import DropdownOption from "./subcomponents/DropdownOption";
@@ -21,17 +20,13 @@ import { GenericObject } from "../types";
21
20
  type DropdownProps = {
22
21
  aria?: { [key: string]: string };
23
22
  autocomplete?: boolean;
24
- children?: React.ReactChild[] | React.ReactChild | ReactElement[];
25
23
  className?: string;
26
- dark?: boolean;
27
24
  data?: { [key: string]: string };
28
25
  htmlOptions?: {[key: string]: string | number | boolean | (() => void)},
29
26
  id?: string;
30
- isClosed?: boolean;
31
- label?: string;
32
- onSelect?: (arg: GenericObject) => null;
27
+ children?: React.ReactChild[] | React.ReactChild | ReactElement[];
33
28
  options: GenericObject;
34
- triggerRef?: any;
29
+ onSelect?: (arg: GenericObject) => null;
35
30
  };
36
31
 
37
32
  const Dropdown = (props: DropdownProps) => {
@@ -40,15 +35,11 @@ const Dropdown = (props: DropdownProps) => {
40
35
  autocomplete = false,
41
36
  children,
42
37
  className,
43
- dark = false,
44
38
  data = {},
45
39
  htmlOptions = {},
46
40
  id,
47
- isClosed = true,
48
- label,
49
- onSelect,
50
41
  options,
51
- triggerRef
42
+ onSelect,
52
43
  } = props;
53
44
 
54
45
  const ariaProps = buildAriaProps(aria);
@@ -60,7 +51,7 @@ const Dropdown = (props: DropdownProps) => {
60
51
  className
61
52
  );
62
53
 
63
- const [isDropDownClosed, setIsDropDownClosed, toggleDropdown] = useDropdown(isClosed);
54
+ const [isDropDownClosed, setIsDropDownClosed, toggleDropdown] = useDropdown();
64
55
 
65
56
  const [filterItem, setFilterItem] = useState("");
66
57
  const [selected, setSelected] = useState<GenericObject>({});
@@ -68,49 +59,25 @@ const Dropdown = (props: DropdownProps) => {
68
59
  const [hasTriggerSubcomponent, setHasTriggerSubcomponent] = useState(true);
69
60
  const [hasContainerSubcomponent, setHasContainerSubcomponent] =
70
61
  useState(true);
62
+
71
63
  //state for keyboard events
72
64
  const [focusedOptionIndex, setFocusedOptionIndex] = useState(-1);
73
65
 
74
66
  const dropdownRef = useRef(null);
75
67
  const inputRef = useRef(null);
76
- const inputWrapperRef = useRef(null);
77
- const dropdownContainerRef = useRef(null);
78
68
 
79
69
  const { trigger, container, otherChildren } =
80
70
  separateChildComponents(children);
81
71
 
72
+ // useEffect to handle clicks outside the dropdown
82
73
  useEffect(() => {
83
- // Set the parent element of the trigger to relative to allow for absolute positioning of the dropdown
84
- //Only needed for when useDropdown hook used with external trigger
85
- if (triggerRef?.current) {
86
- const parentElement = triggerRef.current.parentNode;
87
- if (parentElement) {
88
- parentElement.style.position = 'relative';
89
- }
90
- }
91
- // Handle clicks outside the dropdown
92
74
  const handleClickOutside = (e: MouseEvent) => {
93
- let targetElement = e.target as HTMLElement;
94
- let shouldClose = true;
95
-
96
- while (targetElement && shouldClose) {
97
- //Only needed for when useDropdown hook used with external trigger
98
- if (targetElement.getAttribute('data-dropdown') === 'pb-dropdown-trigger') {
99
- shouldClose = false;
100
- }
101
- targetElement = targetElement.parentElement as HTMLElement;
102
- }
103
- if (
104
- inputWrapperRef.current && !inputWrapperRef.current.contains(e.target) &&
105
- (dropdownContainerRef.current && !dropdownContainerRef.current.contains(e.target)) &&
106
- shouldClose
107
- ) {
75
+ if (dropdownRef.current && !dropdownRef.current.contains(e.target)) {
108
76
  setIsDropDownClosed(true);
109
- setFocusedOptionIndex(-1);
77
+ setFocusedOptionIndex(-1)
110
78
  setIsInputFocused(false);
111
79
  }
112
80
  };
113
-
114
81
  window.addEventListener("click", handleClickOutside);
115
82
  return () => {
116
83
  window.removeEventListener("click", handleClickOutside);
@@ -122,16 +89,11 @@ const Dropdown = (props: DropdownProps) => {
122
89
  setHasContainerSubcomponent(!!container);
123
90
  }, []);
124
91
 
125
- // dropdown to toggle with external control
126
- useEffect(()=> {
127
- setIsDropDownClosed(isClosed)
128
- },[isClosed])
129
92
 
130
93
  const filteredOptions = options?.filter((option: GenericObject) =>
131
94
  option.label.toLowerCase().includes(filterItem.toLowerCase())
132
95
  );
133
96
 
134
- // For keyboard accessibility: Set focus within dropdown to selected item if it exists
135
97
  useEffect(() => {
136
98
  if (!isDropDownClosed) {
137
99
  let newIndex = 0;
@@ -145,7 +107,6 @@ const Dropdown = (props: DropdownProps) => {
145
107
  }
146
108
  }, [isDropDownClosed]);
147
109
 
148
-
149
110
  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
150
111
  setFilterItem(e.target.value);
151
112
  setIsDropDownClosed(false);
@@ -155,7 +116,7 @@ const Dropdown = (props: DropdownProps) => {
155
116
  setSelected(selectedItem);
156
117
  setFilterItem("");
157
118
  setIsDropDownClosed(true);
158
- onSelect && onSelect(selectedItem);
119
+ onSelect(selectedItem);
159
120
  };
160
121
 
161
122
  const handleWrapperClick = () => {
@@ -165,7 +126,7 @@ const Dropdown = (props: DropdownProps) => {
165
126
 
166
127
  const handleBackspace = () => {
167
128
  setSelected({});
168
- onSelect && onSelect(null);
129
+ onSelect(null);
169
130
  setFocusedOptionIndex(-1);
170
131
  };
171
132
 
@@ -176,22 +137,18 @@ const Dropdown = (props: DropdownProps) => {
176
137
  trigger,
177
138
  container,
178
139
  otherChildren,
179
- dark
180
140
  });
181
141
 
182
-
183
142
  return (
184
143
  <div {...ariaProps}
185
144
  {...dataProps}
186
145
  {...htmlProps}
187
146
  className={classes}
188
147
  id={id}
189
- style={triggerRef ? { position: "absolute"} : { position: "relative"}}
190
148
  >
191
149
  <DropdownContext.Provider
192
150
  value={{
193
151
  autocomplete,
194
- dropdownContainerRef,
195
152
  filteredOptions,
196
153
  filterItem,
197
154
  focusedOptionIndex,
@@ -200,7 +157,6 @@ const Dropdown = (props: DropdownProps) => {
200
157
  handleOptionClick,
201
158
  handleWrapperClick,
202
159
  inputRef,
203
- inputWrapperRef,
204
160
  isDropDownClosed,
205
161
  isInputFocused,
206
162
  options,
@@ -210,16 +166,8 @@ const Dropdown = (props: DropdownProps) => {
210
166
  setIsInputFocused,
211
167
  setSelected,
212
168
  toggleDropdown,
213
- triggerRef
214
169
  }}
215
170
  >
216
- {label &&
217
- <Caption
218
- dark={dark}
219
- marginBottom="xs"
220
- text={label}
221
- />
222
- }
223
171
  <div className="dropdown_wrapper"
224
172
  onBlur={() => {
225
173
  // Debounce to delay the execution to prevent jumpiness in Focus state
@@ -256,7 +204,7 @@ const Dropdown = (props: DropdownProps) => {
256
204
  </div>
257
205
  </DropdownContext.Provider>
258
206
  </div>
259
- )
207
+ );
260
208
  };
261
209
 
262
210
  Dropdown.Option = DropdownOption;
@@ -1,20 +1,31 @@
1
- import React from 'react'
1
+ import React, { useState } from 'react'
2
2
  import { Dropdown } from '../../'
3
3
 
4
4
  const DropdownDefault = (props) => {
5
+ // eslint-disable-next-line no-unused-vars
6
+ const [selectedOption, setSelectedOption] = useState();
5
7
 
6
8
  const options = [
7
9
  {
8
10
  label: "United States",
9
11
  value: "United States",
12
+ areaCode: "+1",
13
+ icon: "πŸ‡ΊπŸ‡Έ",
14
+ id: "United-states"
10
15
  },
11
16
  {
12
17
  label: "Canada",
13
18
  value: "Canada",
19
+ areaCode: "+1",
20
+ icon: "πŸ‡¨πŸ‡¦",
21
+ id: "canada"
14
22
  },
15
23
  {
16
24
  label: "Pakistan",
17
25
  value: "Pakistan",
26
+ areaCode: "+92",
27
+ icon: "πŸ‡΅πŸ‡°",
28
+ id: "pakistan"
18
29
  }
19
30
  ];
20
31
 
@@ -22,6 +33,7 @@ const DropdownDefault = (props) => {
22
33
  return (
23
34
  <div>
24
35
  <Dropdown
36
+ onSelect={(selectedItem) => setSelectedOption(selectedItem)}
25
37
  options={options}
26
38
  {...props}
27
39
  >
@@ -1 +0,0 @@
1
- `options` for the Dropdown and `option` for the Dropdown.Option are the only required props for this kit. `options` must be an array of objects. Each object can contain any key/value pairs needed but 'label' and 'value' are required.
@@ -81,7 +81,7 @@ const DropdownWithCustomDisplay = (props) => {
81
81
  />
82
82
  </FlexItem>
83
83
  <FlexItem>
84
- <Badge dark
84
+ <Badge
85
85
  rounded
86
86
  text={option.status}
87
87
  variant={`${
@@ -1,5 +1,3 @@
1
1
  The `customDisplay` prop can be used to customize the display of the selected item by allowing devs to pass in a component that will be rendered to the left of the default text-based display. In this example the Avatar kit is being used.
2
2
 
3
- The `placeholder` prop can also be used to customize the placeholder text for the default Trigger.
4
-
5
- The `onSelect` prop is a function that gives the dev one argument: the selected option. In this example we are using the `onSelect` to set a state with the selected option and using it to customize the `customDisplay`.
3
+ The `placeholder` prop can also be used to customize the placeholder text for the default Trigger.
@@ -1,7 +1,9 @@
1
- import React from 'react'
1
+ import React, { useState } from 'react'
2
2
  import { Dropdown, Icon, Body, FlexItem, Flex } from '../..'
3
3
 
4
4
  const DropdownWithCustomOptions = (props) => {
5
+ // eslint-disable-next-line no-unused-vars
6
+ const [selectedOption, setSelectedOption] = useState();
5
7
 
6
8
  const options = [
7
9
  {
@@ -31,6 +33,7 @@ const DropdownWithCustomOptions = (props) => {
31
33
  return (
32
34
  <div>
33
35
  <Dropdown
36
+ onSelect={(selectedItem) => setSelectedOption(selectedItem)}
34
37
  options={options}
35
38
  {...props}
36
39
  >
@@ -1,7 +1,9 @@
1
- import React from 'react'
1
+ import React, { useState } from 'react'
2
2
  import { Dropdown } from '../..'
3
3
 
4
4
  const DropdownWithCustomPadding = (props) => {
5
+ // eslint-disable-next-line no-unused-vars
6
+ const [selectedOption, setSelectedOption] = useState();
5
7
 
6
8
  const options = [
7
9
  {
@@ -31,6 +33,7 @@ const DropdownWithCustomPadding = (props) => {
31
33
  return (
32
34
  <div>
33
35
  <Dropdown
36
+ onSelect={(selectedItem) => setSelectedOption(selectedItem)}
34
37
  options={options}
35
38
  {...props}
36
39
  >
@@ -3,13 +3,10 @@ examples:
3
3
 
4
4
  react:
5
5
  - dropdown_default: Default
6
- - dropdown_with_label: With Label
7
6
  - dropdown_with_custom_options: Custom Options
8
7
  - dropdown_with_custom_display: Custom Display
9
8
  - dropdown_with_custom_trigger: Custom Trigger
9
+ - dropdown_with_autocomplete: Autocomplete
10
+ - dropdown_with_autocomplete_and_custom_display: Autocomplete with Custom Display
10
11
  - dropdown_with_custom_padding: Custom Padding for Dropdown Options
11
- # - dropdown_with_autocomplete: Autocomplete
12
- # - dropdown_with_autocomplete_and_custom_display: Autocomplete with Custom Display
13
- # - dropdown_with_external_control: useDropdown Hook
14
- # - dropdown_with_hook: useDropdown Hook with Any Trigger
15
12
 
@@ -4,7 +4,4 @@ export { default as DropdownWithCustomOptions } from './_dropdown_with_custom_op
4
4
  export { default as DropdownWithCustomTrigger } from './_dropdown_with_custom_trigger.jsx'
5
5
  export { default as DropdownWithAutocomplete } from './_dropdown_with_autocomplete.jsx'
6
6
  export { default as DropdownWithAutocompleteAndCustomDisplay } from './_dropdown_with_autocomplete_and_custom_display.jsx'
7
- export { default as DropdownWithCustomPadding } from './_dropdown_with_custom_padding.jsx'
8
- export { default as DropdownWithLabel } from './_dropdown_with_label.jsx'
9
- export { default as DropdownWithExternalControl } from './_dropdown_with_external_control.jsx'
10
- export { default as DropdownWithHook } from './_dropdown_with_hook.jsx'
7
+ export { default as DropdownWithCustomPadding } from './_dropdown_with_custom_padding.jsx'