playbook_ui 12.18.0.pre.alpha.PLAY785typeaheadts632 → 12.18.0.pre.alpha.play786multilevelselectimprovements613

Sign up to get free protection for your applications and to get access to all the features.
Files changed (24) hide show
  1. checksums.yaml +4 -4
  2. data/app/pb_kits/playbook/pb_multi_level_select/_multi_level_select.scss +1 -2
  3. data/app/pb_kits/playbook/pb_multi_level_select/_multi_level_select.tsx +15 -6
  4. data/app/pb_kits/playbook/pb_multi_level_select/helper_functions.ts +8 -5
  5. data/app/pb_kits/playbook/pb_table/index.ts +2 -6
  6. data/app/pb_kits/playbook/pb_tooltip/_tooltip.tsx +10 -11
  7. data/app/pb_kits/playbook/pb_tooltip/tooltip.test.jsx +0 -29
  8. data/app/pb_kits/playbook/pb_typeahead/{_typeahead.tsx → _typeahead.jsx} +12 -24
  9. data/app/pb_kits/playbook/pb_typeahead/components/{ClearIndicator.tsx → ClearIndicator.jsx} +4 -2
  10. data/app/pb_kits/playbook/pb_typeahead/components/{Control.tsx → Control.jsx} +7 -5
  11. data/app/pb_kits/playbook/pb_typeahead/components/{IndicatorsContainer.tsx → IndicatorsContainer.jsx} +4 -2
  12. data/app/pb_kits/playbook/pb_typeahead/components/{MenuList.tsx → MenuList.jsx} +2 -0
  13. data/app/pb_kits/playbook/pb_typeahead/components/MultiValue.jsx +62 -0
  14. data/app/pb_kits/playbook/pb_typeahead/components/Option.jsx +39 -0
  15. data/app/pb_kits/playbook/pb_typeahead/components/{Placeholder.tsx → Placeholder.jsx} +9 -7
  16. data/app/pb_kits/playbook/pb_typeahead/components/{ValueContainer.tsx → ValueContainer.jsx} +5 -3
  17. data/app/pb_kits/playbook/pb_typeahead/{index.ts → index.js} +29 -37
  18. data/app/pb_kits/playbook/pb_user/_user.tsx +1 -1
  19. data/app/pb_kits/playbook/tokens/_colors.scss +3 -5
  20. data/lib/playbook/version.rb +1 -1
  21. metadata +12 -13
  22. data/app/pb_kits/playbook/pb_typeahead/components/MultiValue.tsx +0 -66
  23. data/app/pb_kits/playbook/pb_typeahead/components/Option.tsx +0 -37
  24. data/app/pb_kits/playbook/pb_typeahead/types.d.ts +0 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ebfd5fbf4ef024e0e8d72e0571709edfb8738488a45893fe4cb0ae7ffb43910a
4
- data.tar.gz: 8dcb7aea81f460389a352c31d6d78ba8ef9525b6220c83979e0865aa2a4a6f38
3
+ metadata.gz: aec7f79fe2db81a272cf0057d094de657cf8e37d670cc5cf19317a7db77784a4
4
+ data.tar.gz: 3710f7209973f12d8659fe8cc7f1c02a4b96f79e21b88f977401fd32502b1728
5
5
  SHA512:
6
- metadata.gz: 0b7e9a390686d87fff0212071df2a3a44a468266e28e3d8ab24f968a15775edd01132a74839b3af58e71add8eb6884a3c02999f6198110e75fbfbf5f2bbf7519
7
- data.tar.gz: 228b4952c368979aacac5e591c5b2b1c91339a6bae8b1731fef3872a7f5f6833d9763d7743772b86f83ccd3f902154355f1a1f662fd41624af4a0989575ca45c
6
+ metadata.gz: 8d43d3936e4b6bc1f8a4d89685ea0c23d9c093c20d76d875e542e4d6845837d6e7876cf55e1c242c4603fa121854687c2b8d2e9f26f27d0ced474e4acfacf6fb
7
+ data.tar.gz: df3d944e460533d996e15d569f69212c400c901000656a220478e173bbf1ae71c02985c1733e6fa659bf4aecce25ccbc0a8dca084423463f31c76d3fa00635ce
@@ -36,10 +36,9 @@
36
36
  vertical-align: top;
37
37
  width: 0.6em;
38
38
  top: 10px;
39
- transform: rotate(135deg);
40
39
  font-size: 0.5em;
41
40
 
42
- transform: rotate(-45deg);
41
+ transform: rotate(45deg);
43
42
  top: 12px;
44
43
  }
45
44
 
@@ -42,17 +42,25 @@ const MultiLevelSelect = (props: MultiLevelSelectProps) => {
42
42
  const updatedData = formattedData.map((item: any) => {
43
43
  if (item.id === currentNode._id) {
44
44
  if (currentNode.checked) {
45
- checkIt(item, selectedItems, setSelectedItems);
45
+ checkIt(item, selectedItems, setSelectedItems, false);
46
46
  } else {
47
- unCheckIt(item, selectedItems, setSelectedItems);
47
+ unCheckIt(item, selectedItems, setSelectedItems, false);
48
48
  }
49
49
  } else if (item.children) {
50
50
  const foundItem = findItemById(item.children, currentNode._id);
51
51
  if (foundItem) {
52
52
  if (currentNode.checked) {
53
- checkIt(foundItem, selectedItems, setSelectedItems);
53
+ checkIt(foundItem, selectedItems, setSelectedItems, false);
54
+ if (currentNode._parent) {
55
+ const parent = findItemById(formattedData, currentNode._parent);
56
+ parent.expanded = true;
57
+ }
54
58
  } else {
55
- unCheckIt(foundItem, selectedItems, setSelectedItems);
59
+ unCheckIt(foundItem, selectedItems, setSelectedItems, false);
60
+ if (currentNode._parent) {
61
+ const parent = findItemById(formattedData, currentNode._parent);
62
+ parent.expanded = true;
63
+ }
56
64
  }
57
65
  }
58
66
  }
@@ -92,17 +100,18 @@ const MultiLevelSelect = (props: MultiLevelSelectProps) => {
92
100
  treeData={formattedData}
93
101
  onChange={(
94
102
  // @ts-ignore
95
- selectedNodes: { [key: string]: any }[],
103
+ selectedNodes: { [key: string]: any }[],
96
104
  currentNode: { [key: string]: any }[]
97
105
  ) => {
98
106
  setCheckedData(currentNode);
99
107
  onSelect(currentNode);
108
+
100
109
  }}
101
110
  id={id}
102
111
  {...props}
103
112
  />
104
113
  );
105
- }, [formattedData]);
114
+ }, [formattedData])
106
115
 
107
116
  return (
108
117
  <div {...ariaProps} {...dataProps} className={classes} id={id}>
@@ -19,19 +19,20 @@ export const findItemById = (
19
19
  export const checkIt = (
20
20
  foundItem: { [key: string]: any },
21
21
  selectedItems: any[],
22
- setSelectedItems: Function
22
+ setSelectedItems: Function,
23
+ expand: boolean
23
24
  ) => {
24
25
  if (!foundItem) {
25
26
  return;
26
27
  }
27
28
 
28
29
  foundItem.checked = true;
29
- foundItem.expanded = true;
30
+ foundItem.expanded = expand;
30
31
  selectedItems.push(foundItem);
31
32
 
32
33
  if (foundItem.children) {
33
34
  foundItem.children.map((x: any) => {
34
- checkIt(x, selectedItems, setSelectedItems);
35
+ checkIt(x, selectedItems, setSelectedItems, expand);
35
36
  });
36
37
  }
37
38
 
@@ -41,19 +42,21 @@ export const checkIt = (
41
42
  export const unCheckIt = (
42
43
  foundItem: { [key: string]: any },
43
44
  selectedItems: any,
44
- setSelectedItems: any
45
+ setSelectedItems: any,
46
+ expand: boolean
45
47
  ) => {
46
48
  if (!foundItem) {
47
49
  return;
48
50
  }
49
51
 
50
52
  foundItem.checked = false;
53
+ foundItem.expanded = false;
51
54
  const newSelectedItems = selectedItems.filter(
52
55
  (item: any) => item.id !== foundItem.id
53
56
  );
54
57
  if (foundItem.children) {
55
58
  foundItem.children.map((x: any) => {
56
- unCheckIt(x, selectedItems, setSelectedItems);
59
+ unCheckIt(x, selectedItems, setSelectedItems, expand);
57
60
  });
58
61
  }
59
62
  setSelectedItems([...newSelectedItems]);
@@ -11,12 +11,8 @@ export default class PbTable extends PbEnhancedElement {
11
11
  // Each Table
12
12
  [].forEach.call(tables, (table: HTMLTableElement) => {
13
13
  // Header Titles
14
- let headers: string[] = [];
15
- [].forEach.call(table.querySelectorAll('th'), (header: HTMLTableCellElement) => {
16
- let colSpan = header.colSpan
17
- for (let i = 0; i < colSpan; i++) {
18
- headers.push(header.textContent.replace(/\r?\n|\r/, ''));
19
- }
14
+ var headers = [].map.call(table.querySelectorAll('th'), (header: Element) => {
15
+ return header.textContent.replace(/\r?\n|\r/, '')
20
16
  });
21
17
 
22
18
  // for each row in tbody
@@ -6,7 +6,7 @@ import {
6
6
  offset,
7
7
  Placement,
8
8
  safePolygon,
9
- shift,
9
+ shift,
10
10
  useFloating,
11
11
  useHover,
12
12
  useInteractions,
@@ -17,6 +17,9 @@ import { GlobalProps, globalProps } from "../utilities/globalProps"
17
17
  import { buildAriaProps, buildDataProps } from "../utilities/props"
18
18
  import Flex from "../pb_flex/_flex"
19
19
 
20
+
21
+
22
+
20
23
  type TooltipProps = {
21
24
  aria?: { [key: string]: string },
22
25
  className?: string | string[],
@@ -26,8 +29,8 @@ type TooltipProps = {
26
29
  icon?: string,
27
30
  interaction?: boolean,
28
31
  placement?: Placement,
29
- position?: "absolute" | "fixed";
30
32
  text: string,
33
+ zIndex?: Pick<GlobalProps, "ZIndex">,
31
34
  } & GlobalProps
32
35
 
33
36
  const Tooltip = (props: TooltipProps): React.ReactElement => {
@@ -40,7 +43,6 @@ const Tooltip = (props: TooltipProps): React.ReactElement => {
40
43
  icon = null,
41
44
  interaction = false,
42
45
  placement: preferredPlacement = "top",
43
- position = "absolute",
44
46
  text,
45
47
  zIndex,
46
48
  ...rest
@@ -48,26 +50,24 @@ const Tooltip = (props: TooltipProps): React.ReactElement => {
48
50
 
49
51
  const dataProps: { [key: string]: any } = buildDataProps(data)
50
52
  const ariaProps: { [key: string]: any } = buildAriaProps(aria)
51
-
53
+
52
54
  const css = classnames(
53
55
  globalProps({...rest}),
54
56
  className,
55
57
  )
56
58
  const [open, setOpen] = useState(false)
57
59
  const arrowRef = useRef(null)
58
-
59
-
60
60
  const {
61
+
61
62
  context,
62
63
  floating,
63
- middlewareData: { arrow: { x: arrowX, y: arrowY } = {}, },
64
+ middlewareData: { arrow: { x: arrowX, y: arrowY } = {} },
64
65
  placement,
65
66
  reference,
66
67
  strategy,
67
68
  x,
68
69
  y,
69
70
  } = useFloating({
70
- strategy: position,
71
71
  middleware: [
72
72
  arrow({
73
73
  element: arrowRef,
@@ -87,7 +87,6 @@ const Tooltip = (props: TooltipProps): React.ReactElement => {
87
87
  placement: preferredPlacement
88
88
  })
89
89
 
90
-
91
90
  const { getFloatingProps } = useInteractions([
92
91
  useHover(context, {
93
92
  delay,
@@ -143,7 +142,7 @@ const Tooltip = (props: TooltipProps): React.ReactElement => {
143
142
  className="arrow_bg"
144
143
  ref={arrowRef}
145
144
  style={{
146
- position: "absolute",
145
+ position: strategy,
147
146
  left: arrowX != null ? `${arrowX}px` : "",
148
147
  top: arrowY != null ? `${arrowY}px` : "",
149
148
  [staticSide]: "-5px",
@@ -155,4 +154,4 @@ const Tooltip = (props: TooltipProps): React.ReactElement => {
155
154
  )
156
155
  }
157
156
 
158
- export default Tooltip
157
+ export default Tooltip
@@ -65,32 +65,3 @@ test("closes on mouseleave", async () => {
65
65
 
66
66
  cleanup();
67
67
  });
68
-
69
- test("has default position absolute", async () => {
70
- render(<TooltipTest />);
71
-
72
- fireEvent.mouseEnter(screen.getByRole("tooltip_trigger"));
73
- await waitFor(() => {
74
- expect(screen.queryByRole("tooltip")).toHaveStyle({"position": "absolute"});
75
- cleanup();
76
- })
77
-
78
- cleanup();
79
- });
80
-
81
- test("has position fixed", async () => {
82
- render(
83
- <Tooltip
84
- data={{ testid: "fixed-position-test" }}
85
- position="fixed"
86
- />
87
- );
88
-
89
- fireEvent.mouseEnter(screen.getByRole("tooltip_trigger"));
90
- await waitFor(() => {
91
- expect(screen.queryByRole("tooltip")).toHaveStyle({"position": "fixed"});
92
- cleanup();
93
- })
94
-
95
- cleanup();
96
- });
@@ -1,3 +1,5 @@
1
+ /* @flow */
2
+
1
3
  import React from 'react'
2
4
  import Select from 'react-select'
3
5
  import AsyncSelect from 'react-select/async'
@@ -17,7 +19,6 @@ import Placeholder from './components/Placeholder'
17
19
  import ValueContainer from './components/ValueContainer'
18
20
 
19
21
  import { noop, buildDataProps } from '../utilities/props'
20
- import { Noop } from '../types'
21
22
 
22
23
  /**
23
24
  * @typedef {object} Props
@@ -32,28 +33,16 @@ type TypeaheadProps = {
32
33
  components?: object,
33
34
  createable?: boolean,
34
35
  dark?: boolean,
35
- data?: { [key: string]: string },
36
+ data?: object,
36
37
  error?: string,
37
38
  id?: string,
38
39
  label?: string,
39
- loadOptions?: string | Noop,
40
+ loadOptions?: string,
40
41
  getOptionLabel?: string | (() => any),
41
42
  getOptionValue?: string | (() => any),
42
43
  name?: string,
43
44
  }
44
45
 
45
- export type SelectValueType = {
46
- label: string,
47
- value: string,
48
- imageUrl?: string,
49
- }
50
-
51
- type TagOnChangeValues = {
52
- action?: string,
53
- option?: SelectValueType,
54
- removedValue?: string,
55
- }
56
-
57
46
  /**
58
47
  * @constant {React.ReactComponent} Typeahead
59
48
  * @param {TypeaheadProps} props - props as described at https://react-select.com/props
@@ -78,7 +67,7 @@ const Typeahead = ({
78
67
  Control,
79
68
  ClearIndicator,
80
69
  IndicatorsContainer,
81
- IndicatorSeparator: null as null,
70
+ IndicatorSeparator: null,
82
71
  MenuList,
83
72
  MultiValue,
84
73
  Option,
@@ -96,9 +85,8 @@ const Typeahead = ({
96
85
  isSearchable: true,
97
86
  name,
98
87
  multiKit: '',
99
- onCreateOption: null as null,
88
+ onCreateOption: null,
100
89
  plusIcon: false,
101
- onMultiValueClick: (_option: SelectValueType) => { },
102
90
  ...props,
103
91
  }
104
92
 
@@ -108,7 +96,7 @@ const Typeahead = ({
108
96
  : (async ? AsyncSelect : Select)
109
97
  )
110
98
 
111
- const handleOnChange = (_data: SelectValueType, { action, option, removedValue }: TagOnChangeValues) => {
99
+ const handleOnChange = (_data, { action, option, removedValue }) => {
112
100
  if (action === 'select-option') {
113
101
  if (selectProps.onMultiValueClick) selectProps.onMultiValueClick(option)
114
102
  const multiValueClearEvent = new CustomEvent(`pb-typeahead-kit-${selectProps.id}-result-option-select`, { detail: option ? option : _data })
@@ -135,13 +123,13 @@ const Typeahead = ({
135
123
 
136
124
  return (
137
125
  <div {...dataProps}
138
- className={classnames(classes, inlineClass)}
126
+ className={classnames(classes, inlineClass)}
139
127
  >
140
128
  <Tag
141
- classNamePrefix="typeahead-kit-select"
142
- error={error}
143
- onChange={handleOnChange}
144
- {...selectProps}
129
+ classNamePrefix="typeahead-kit-select"
130
+ error={error}
131
+ onChange={handleOnChange}
132
+ {...selectProps}
145
133
  />
146
134
  </div>
147
135
  )
@@ -1,3 +1,5 @@
1
+ /* @flow */
2
+
1
3
  import React, { useEffect } from 'react'
2
4
  import { components } from 'react-select'
3
5
 
@@ -9,8 +11,8 @@ const ClearContainer = (props: any) => {
9
11
 
10
12
  return (
11
13
  <components.ClearIndicator
12
- className="clear_indicator"
13
- {...props}
14
+ className="clear_indicator"
15
+ {...props}
14
16
  />
15
17
  )
16
18
  }
@@ -1,3 +1,5 @@
1
+ /* @flow */
2
+
1
3
  import React from 'react'
2
4
  import { components } from 'react-select'
3
5
 
@@ -11,14 +13,14 @@ type Props = {
11
13
  const TypeaheadControl = (props: Props) => (
12
14
  <div className="pb_typeahead_wrapper">
13
15
  <TextInput
14
- dark={props.selectProps.dark}
15
- error={props.selectProps.error}
16
- label={props.selectProps.label}
16
+ dark={props.selectProps.dark}
17
+ error={props.selectProps.error}
18
+ label={props.selectProps.label}
17
19
  >
18
20
  <Flex>
19
21
  <components.Control
20
- className="text_input"
21
- {...props}
22
+ className="text_input"
23
+ {...props}
22
24
  />
23
25
  </Flex>
24
26
  </TextInput>
@@ -1,10 +1,12 @@
1
+ /* @flow */
2
+
1
3
  import React from 'react'
2
4
  import { components } from 'react-select'
3
5
 
4
6
  const IndicatorsContainer = (props: any) => (
5
7
  <components.IndicatorsContainer
6
- className="text_input_indicators"
7
- {...props}
8
+ className="text_input_indicators"
9
+ {...props}
8
10
  />
9
11
  )
10
12
 
@@ -1,3 +1,5 @@
1
+ /* @flow */
2
+
1
3
  import React from 'react'
2
4
  import { components } from 'react-select'
3
5
 
@@ -0,0 +1,62 @@
1
+ /* @flow */
2
+
3
+ import React from 'react'
4
+ import { components } from 'react-select'
5
+
6
+ import Badge from '../../pb_badge/_badge'
7
+ import FormPill from '../../pb_form_pill/_form_pill'
8
+
9
+ type Props = {
10
+ data: object,
11
+ multiValueTemplate: any,
12
+ removeProps: any,
13
+ selectProps: any,
14
+ }
15
+
16
+ const MultiValue = (props: Props) => {
17
+ const { removeProps } = props
18
+ const { imageUrl, label } = props.data
19
+ const { multiKit } = props.selectProps
20
+
21
+ const formPillProps = {
22
+ marginRight: 'xs',
23
+ name: label,
24
+ }
25
+
26
+ if (typeof imageUrl === 'string') formPillProps.avatarUrl = imageUrl
27
+
28
+ return (
29
+ <components.MultiValueContainer
30
+ className="text_input_multivalue_container"
31
+ {...props}
32
+ >
33
+ <If condition={multiKit === 'badge'}>
34
+ <Badge
35
+ closeProps={removeProps}
36
+ removeIcon
37
+ text={label}
38
+ variant="primary"
39
+ />
40
+ <Else />
41
+ <If condition={imageUrl}>
42
+ <FormPill
43
+ avatarUrl={imageUrl}
44
+ closeProps={removeProps}
45
+ marginRight="xs"
46
+ name={label}
47
+ size={multiKit === 'smallPill' ? 'small' : ''}
48
+ />
49
+ <Else />
50
+ <FormPill
51
+ closeProps={removeProps}
52
+ marginRight="xs"
53
+ size={multiKit === 'smallPill' ? 'small' : ''}
54
+ text={label}
55
+ />
56
+ </If>
57
+ </If>
58
+ </components.MultiValueContainer>
59
+ )
60
+ }
61
+
62
+ export default MultiValue
@@ -0,0 +1,39 @@
1
+ /* @flow */
2
+
3
+ import React from 'react'
4
+ import { components } from 'react-select'
5
+
6
+ import User from '../../pb_user/_user'
7
+
8
+ const Option = (props: any) => {
9
+ const {
10
+ imageUrl,
11
+ } = props.data
12
+ const { valueComponent } = props.selectProps
13
+
14
+ return (
15
+ <components.Option {...props}>
16
+ <div>
17
+ <Choose>
18
+ <When condition={!valueComponent && imageUrl}>
19
+ <User
20
+ align="left"
21
+ avatarUrl={imageUrl}
22
+ dark={props.selectProps.dark}
23
+ name={props.label}
24
+ orientation="horizontal"
25
+ />
26
+ </When>
27
+ <When condition={valueComponent}>
28
+ { valueComponent(props.data) }
29
+ </When>
30
+ <Otherwise>
31
+ {props.label}
32
+ </Otherwise>
33
+ </Choose>
34
+ </div>
35
+ </components.Option>
36
+ )
37
+ }
38
+
39
+ export default Option
@@ -1,3 +1,5 @@
1
+ /* @flow */
2
+
1
3
  import React from 'react'
2
4
  import { components } from 'react-select'
3
5
 
@@ -7,18 +9,18 @@ import Icon from '../../pb_icon/_icon'
7
9
  const Placeholder = (props: any) => (
8
10
  <>
9
11
  <Flex
10
- align="center"
11
- className="placeholder"
12
+ align="center"
13
+ className="placeholder"
12
14
  >
13
15
  <components.IndicatorsContainer
14
- {...props}
16
+ {...props}
15
17
  />
16
- {props.selectProps.plusIcon &&
18
+ <If condition={props.selectProps.plusIcon}>
17
19
  <Icon
18
- className="typeahead-plus-icon"
19
- icon="plus"
20
+ className="typeahead-plus-icon"
21
+ icon="plus"
20
22
  />
21
- }
23
+ </If>
22
24
  </Flex>
23
25
  </>
24
26
  )
@@ -1,10 +1,12 @@
1
+ /* @flow */
2
+
1
3
  import React from 'react'
2
4
  import { components } from 'react-select'
3
5
 
4
- const ValueContainer = (props: any) => (
6
+ const ValueContainer = (props: Props) => (
5
7
  <components.ValueContainer
6
- className="text_input_value_container"
7
- {...props}
8
+ className="text_input_value_container"
9
+ {...props}
8
10
  />
9
11
  )
10
12
 
@@ -2,26 +2,18 @@ import PbEnhancedElement from '../pb_enhanced_element'
2
2
  import { debounce } from 'lodash'
3
3
 
4
4
  export default class PbTypeahead extends PbEnhancedElement {
5
- _searchInput: HTMLInputElement
6
- _resultsElement: HTMLElement
7
- _debouncedSearch: Function
8
- _resultsLoadingIndicator: HTMLElement
9
- _resultOptionTemplate: HTMLElement
10
- _resultsOptionCache: Map<string, Array<DocumentFragment>>
11
- _searchContext: string
12
-
13
5
  static get selector() {
14
6
  return '[data-pb-typeahead-kit]'
15
7
  }
16
8
 
17
9
  connect() {
18
- this.element.addEventListener('keydown', (event: KeyboardEvent) => this.handleKeydown(event))
10
+ this.element.addEventListener('keydown', (event) => this.handleKeydown(event))
19
11
  this.searchInput.addEventListener('focus', () => this.debouncedSearch())
20
12
  this.searchInput.addEventListener('input', () => this.debouncedSearch())
21
- this.resultsElement.addEventListener('click', (event: MouseEvent) => this.optionSelected(event))
13
+ this.resultsElement.addEventListener('click', (event) => this.optionSelected(event))
22
14
  }
23
15
 
24
- handleKeydown(event: KeyboardEvent) {
16
+ handleKeydown(event) {
25
17
  if (event.key === 'ArrowUp') {
26
18
  event.preventDefault()
27
19
  this.focusPreviousOption()
@@ -32,7 +24,7 @@ export default class PbTypeahead extends PbEnhancedElement {
32
24
  }
33
25
 
34
26
  search() {
35
- if (this.searchTerm.length < parseInt(this.searchTermMinimumLength)) return this.clearResults()
27
+ if (this.searchTerm.length < this.searchTermMinimumLength) return this.clearResults()
36
28
 
37
29
  this.toggleResultsLoadingIndicator(true)
38
30
  this.showResults()
@@ -42,17 +34,17 @@ export default class PbTypeahead extends PbEnhancedElement {
42
34
  const search = {
43
35
  searchingFor: searchTerm,
44
36
  searchingContext: searchContext,
45
- setResults: (results: Array<DocumentFragment>) => {
37
+ setResults: (results) => {
46
38
  this.resultsCacheUpdate(searchTerm, searchContext, results)
47
39
  },
48
40
  }
49
41
  this.element.dispatchEvent(new CustomEvent('pb-typeahead-kit-search', { bubbles: true, detail: search }))
50
42
  }
51
43
 
52
- resultsCacheUpdate(searchTerm: string, searchContext: string, results: Array<DocumentFragment>) {
44
+ resultsCacheUpdate(searchTerm, searchContext, results) {
53
45
  const searchTermAndContext = this.cacheKeyFor(searchTerm, searchContext)
54
46
  if (this.resultsOptionCache.has(searchTermAndContext)) this.resultsOptionCache.delete(searchTermAndContext)
55
- if (this.resultsOptionCache.size > 32) this.resultsOptionCache.delete(this.resultsOptionCache.keys().next().value)
47
+ if (this.resultsOptionCache.size > 32) this.resultsOptionCache.delete(this.resultsOptionCache.keys[0])
56
48
 
57
49
  this.resultsOptionCache.set(searchTermAndContext, results)
58
50
  this.showResults()
@@ -65,7 +57,7 @@ export default class PbTypeahead extends PbEnhancedElement {
65
57
  get debouncedSearch() {
66
58
  return this._debouncedSearch = (
67
59
  this._debouncedSearch ||
68
- debounce(this.search, parseInt(this.searchDebounceTimeout)).bind(this)
60
+ debounce(this.search, this.searchDebounceTimeout).bind(this)
69
61
  )
70
62
  }
71
63
 
@@ -78,12 +70,12 @@ export default class PbTypeahead extends PbEnhancedElement {
78
70
  this.resultsElement.appendChild(this.newResultOption(result.cloneNode(true)))
79
71
  }
80
72
  for (const result of this.resultsElement.querySelectorAll('[data-result-option-item]')) {
81
- result.addEventListener('mousedown', (event: MouseEvent) => this.optionSelected(event))
73
+ result.addEventListener('mousedown', (event) => this.optionSelected(event))
82
74
  }
83
75
  }
84
76
 
85
- optionSelected(event: MouseEvent) {
86
- const resultOption = (event.target as Element).closest('[data-result-option-item]')
77
+ optionSelected(event) {
78
+ const resultOption = event.target.closest('[data-result-option-item]')
87
79
  if (!resultOption) return
88
80
 
89
81
  this.resultsCacheClear()
@@ -97,8 +89,8 @@ export default class PbTypeahead extends PbEnhancedElement {
97
89
  this.resultsElement.innerHTML = ''
98
90
  }
99
91
 
100
- newResultOption(content: DocumentFragment) {
101
- const resultOption = (this.resultOptionTemplate as HTMLTemplateElement).content.cloneNode(true) as Element
92
+ newResultOption(content) {
93
+ const resultOption = this.resultOptionTemplate.content.cloneNode(true)
102
94
  resultOption.querySelector('slot[name="content"]').replaceWith(content)
103
95
  return resultOption
104
96
  }
@@ -108,9 +100,9 @@ export default class PbTypeahead extends PbEnhancedElement {
108
100
  const previousIndex = currentIndex - 1
109
101
  const previousOptionItem = (
110
102
  this.resultOptionItems[previousIndex] ||
111
- this.resultOptionItems[this.resultOptionItems.length - 1]
112
- );
113
- (previousOptionItem as HTMLElement).focus()
103
+ this.resultOptionItems[this.resultOptionItems.length - 1]
104
+ )
105
+ previousOptionItem.focus()
114
106
  }
115
107
 
116
108
  focusNextOption() {
@@ -118,9 +110,9 @@ export default class PbTypeahead extends PbEnhancedElement {
118
110
  const nextIndex = currentIndex + 1
119
111
  const nextOptionItem = (
120
112
  this.resultOptionItems[nextIndex] ||
121
- this.resultOptionItems[0]
122
- );
123
- (nextOptionItem as HTMLElement).focus()
113
+ this.resultOptionItems[0]
114
+ )
115
+ nextOptionItem.focus()
124
116
  }
125
117
 
126
118
  get resultOptionItems() {
@@ -142,11 +134,11 @@ export default class PbTypeahead extends PbEnhancedElement {
142
134
  get searchContext() {
143
135
  if (this._searchContext) return this._searchContext
144
136
 
145
- const selector = (this.element as HTMLElement).dataset.searchContextValueSelector
146
- if (selector) return ((
137
+ const selector = this.element.dataset.searchContextValueSelector
138
+ if (selector) return (
147
139
  this.element.parentNode.querySelector(selector) ||
148
- this.element.closest(selector)
149
- ) as HTMLInputElement).value
140
+ this.element.closest(selector)
141
+ ).value
150
142
 
151
143
  return null
152
144
  }
@@ -159,7 +151,7 @@ export default class PbTypeahead extends PbEnhancedElement {
159
151
  return this.cacheKeyFor(this.searchTerm, this.searchContext)
160
152
  }
161
153
 
162
- cacheKeyFor(searchTerm: string, searchContext: string) {
154
+ cacheKeyFor(searchTerm, searchContext) {
163
155
  return [searchTerm, JSON.stringify(searchContext)].join()
164
156
  }
165
157
 
@@ -168,11 +160,11 @@ export default class PbTypeahead extends PbEnhancedElement {
168
160
  }
169
161
 
170
162
  get searchTermMinimumLength() {
171
- return (this.element as HTMLElement).dataset.pbTypeaheadKitSearchTermMinimumLength
163
+ return this.element.dataset.pbTypeaheadKitSearchTermMinimumLength
172
164
  }
173
165
 
174
166
  get searchDebounceTimeout() {
175
- return (this.element as HTMLElement).dataset.pbTypeaheadKitSearchDebounceTimeout
167
+ return this.element.dataset.pbTypeaheadKitSearchDebounceTimeout
176
168
  }
177
169
 
178
170
  get resultsElement() {
@@ -200,9 +192,9 @@ export default class PbTypeahead extends PbEnhancedElement {
200
192
  )
201
193
  }
202
194
 
203
- toggleResultsLoadingIndicator(visible: boolean) {
204
- var visibilityProperty = '0'
205
- if (visible) visibilityProperty = '1'
195
+ toggleResultsLoadingIndicator(visible) {
196
+ var visibilityProperty = 0
197
+ if (visible) visibilityProperty = 1
206
198
  this.resultsLoadingIndicator.style.opacity = visibilityProperty
207
199
  }
208
200
  }
@@ -18,7 +18,7 @@ type UserProps = {
18
18
  data?: {[key: string]: string},
19
19
  id?: string,
20
20
  name?: string,
21
- orientation?: "horizontal" | "vertical",
21
+ orientation?: "horiztonal" | "vertical",
22
22
  size?: "sm" | "md" | "lg",
23
23
  subtitle?: string | Array<Node> | Node,
24
24
  territory?: string,
@@ -68,7 +68,7 @@ $background_colors: (
68
68
 
69
69
  /* Card colors ------------------*/
70
70
  $card_light: $white !default;
71
- $card_dark: mix(white, $bg_dark, 10%) !default;
71
+ $card_dark: rgba($white, $opacity_1) !default;
72
72
  $card_colors: (
73
73
  card_light: $card_light,
74
74
  card_dark: $card_dark
@@ -109,18 +109,16 @@ $focus_input_colors: (
109
109
 
110
110
  /* Border colors ----------------------*/
111
111
  $border_light: #E4E8F0 !default;
112
- $border_dark: mix(white, $bg_dark, 20%) !default;
112
+ $border_dark: rgba($white, $opacity_1) !default;
113
113
  $border_colors: (
114
114
  border_light: $border_light,
115
115
  border_dark: $border_dark
116
116
  );
117
117
 
118
118
  /* Shadow colors ----------------------*/
119
- $shadow: rgba(#3C6AAC, $opacity_2) !default;
120
- $shadow_dark: $bg_dark !default;
119
+ $shadow: rgba(#3C6AAC, $opacity_2) !default;
121
120
  $shadow_colors: (
122
121
  shadow: $shadow,
123
- shadow_dark: $shadow_dark,
124
122
  );
125
123
 
126
124
  /* Text colors ------------------------*/
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Playbook
4
4
  PREVIOUS_VERSION = "12.18.0"
5
- VERSION = "12.18.0.pre.alpha.PLAY785typeaheadts632"
5
+ VERSION = "12.18.0.pre.alpha.play786multilevelselectimprovements613"
6
6
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: playbook_ui
3
3
  version: !ruby/object:Gem::Version
4
- version: 12.18.0.pre.alpha.PLAY785typeaheadts632
4
+ version: 12.18.0.pre.alpha.play786multilevelselectimprovements613
5
5
  platform: ruby
6
6
  authors:
7
7
  - Power UX
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2023-05-09 00:00:00.000000000 Z
12
+ date: 2023-05-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: actionpack
@@ -2248,17 +2248,17 @@ files:
2248
2248
  - app/pb_kits/playbook/pb_treemap_chart/docs/index.js
2249
2249
  - app/pb_kits/playbook/pb_treemap_chart/treemap_chart.html.erb
2250
2250
  - app/pb_kits/playbook/pb_treemap_chart/treemap_chart.rb
2251
+ - app/pb_kits/playbook/pb_typeahead/_typeahead.jsx
2251
2252
  - app/pb_kits/playbook/pb_typeahead/_typeahead.scss
2252
2253
  - app/pb_kits/playbook/pb_typeahead/_typeahead.test.jsx
2253
- - app/pb_kits/playbook/pb_typeahead/_typeahead.tsx
2254
- - app/pb_kits/playbook/pb_typeahead/components/ClearIndicator.tsx
2255
- - app/pb_kits/playbook/pb_typeahead/components/Control.tsx
2256
- - app/pb_kits/playbook/pb_typeahead/components/IndicatorsContainer.tsx
2257
- - app/pb_kits/playbook/pb_typeahead/components/MenuList.tsx
2258
- - app/pb_kits/playbook/pb_typeahead/components/MultiValue.tsx
2259
- - app/pb_kits/playbook/pb_typeahead/components/Option.tsx
2260
- - app/pb_kits/playbook/pb_typeahead/components/Placeholder.tsx
2261
- - app/pb_kits/playbook/pb_typeahead/components/ValueContainer.tsx
2254
+ - app/pb_kits/playbook/pb_typeahead/components/ClearIndicator.jsx
2255
+ - app/pb_kits/playbook/pb_typeahead/components/Control.jsx
2256
+ - app/pb_kits/playbook/pb_typeahead/components/IndicatorsContainer.jsx
2257
+ - app/pb_kits/playbook/pb_typeahead/components/MenuList.jsx
2258
+ - app/pb_kits/playbook/pb_typeahead/components/MultiValue.jsx
2259
+ - app/pb_kits/playbook/pb_typeahead/components/Option.jsx
2260
+ - app/pb_kits/playbook/pb_typeahead/components/Placeholder.jsx
2261
+ - app/pb_kits/playbook/pb_typeahead/components/ValueContainer.jsx
2262
2262
  - app/pb_kits/playbook/pb_typeahead/docs/_description.md
2263
2263
  - app/pb_kits/playbook/pb_typeahead/docs/_footer.md
2264
2264
  - app/pb_kits/playbook/pb_typeahead/docs/_typeahead_async_createable.jsx
@@ -2289,10 +2289,9 @@ files:
2289
2289
  - app/pb_kits/playbook/pb_typeahead/docs/_typeahead_without_pills.md
2290
2290
  - app/pb_kits/playbook/pb_typeahead/docs/example.yml
2291
2291
  - app/pb_kits/playbook/pb_typeahead/docs/index.js
2292
- - app/pb_kits/playbook/pb_typeahead/index.ts
2292
+ - app/pb_kits/playbook/pb_typeahead/index.js
2293
2293
  - app/pb_kits/playbook/pb_typeahead/typeahead.html.erb
2294
2294
  - app/pb_kits/playbook/pb_typeahead/typeahead.rb
2295
- - app/pb_kits/playbook/pb_typeahead/types.d.ts
2296
2295
  - app/pb_kits/playbook/pb_user/_user.scss
2297
2296
  - app/pb_kits/playbook/pb_user/_user.tsx
2298
2297
  - app/pb_kits/playbook/pb_user/docs/_description.md
@@ -1,66 +0,0 @@
1
- import React from 'react'
2
- import { components } from 'react-select'
3
-
4
- import Badge from '../../pb_badge/_badge'
5
- import FormPill from '../../pb_form_pill/_form_pill'
6
- import { SelectValueType } from '../_typeahead'
7
-
8
- type Props = {
9
- data: SelectValueType,
10
- multiValueTemplate: any,
11
- removeProps: any,
12
- selectProps: any,
13
- }
14
-
15
- const MultiValue = (props: Props) => {
16
- const { removeProps } = props
17
- const { imageUrl, label } = props.data
18
- const { multiKit } = props.selectProps
19
-
20
- const formPillProps = {
21
- marginRight: 'xs',
22
- name: label,
23
- avatarUrl: '',
24
- }
25
-
26
- if (typeof imageUrl === 'string') formPillProps.avatarUrl = imageUrl
27
-
28
- return (
29
- <components.MultiValueContainer
30
- className="text_input_multivalue_container"
31
- {...props}
32
- >
33
- {multiKit === 'badge' &&
34
- <Badge
35
- closeProps={removeProps}
36
- removeIcon
37
- text={label}
38
- variant="primary"
39
- />
40
- }
41
-
42
- {multiKit !== 'badge' && imageUrl &&
43
- <FormPill
44
- avatarUrl={imageUrl}
45
- closeProps={removeProps}
46
- marginRight="xs"
47
- name={label}
48
- size={multiKit === 'smallPill' ? 'small' : ''}
49
- text=''
50
- />
51
- }
52
-
53
- {multiKit !== 'badge' && !imageUrl &&
54
- <FormPill
55
- closeProps={removeProps}
56
- marginRight="xs"
57
- name=''
58
- size={multiKit === 'smallPill' ? 'small' : ''}
59
- text={label}
60
- />
61
- }
62
- </components.MultiValueContainer>
63
- )
64
- }
65
-
66
- export default MultiValue
@@ -1,37 +0,0 @@
1
- import React from 'react'
2
- import { components } from 'react-select'
3
-
4
- import User from '../../pb_user/_user'
5
-
6
- const Option = (props: any) => {
7
- const {
8
- imageUrl,
9
- } = props.data
10
- const { valueComponent } = props.selectProps
11
-
12
- return (
13
- <components.Option {...props}>
14
- <>
15
- {!valueComponent && imageUrl &&
16
- <User
17
- align="left"
18
- avatarUrl={imageUrl}
19
- dark={props.selectProps.dark}
20
- name={props.label}
21
- orientation="horizontal"
22
- />
23
- }
24
-
25
- {valueComponent &&
26
- valueComponent(props.data)
27
- }
28
-
29
- {!valueComponent && !imageUrl &&
30
- props.label
31
- }
32
- </>
33
- </components.Option>
34
- )
35
- }
36
-
37
- export default Option
@@ -1,2 +0,0 @@
1
- declare module 'react-select'
2
- declare module 'react-select/*'