playbook_ui 12.7.1 → 12.8.0.pre.alpha.PLAY645typescriptprogresstep298

Sign up to get free protection for your applications and to get access to all the features.
Files changed (28) hide show
  1. checksums.yaml +4 -4
  2. data/app/pb_kits/playbook/pb_avatar/_avatar.tsx +2 -2
  3. data/app/pb_kits/playbook/pb_multi_level_select/_multi_level_select.tsx +43 -17
  4. data/app/pb_kits/playbook/pb_multi_level_select/_multi_select_helper.tsx +4 -3
  5. data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_return_all_selected.html.erb +71 -0
  6. data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_return_all_selected.jsx +87 -0
  7. data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_return_all_selected.md +3 -0
  8. data/app/pb_kits/playbook/pb_multi_level_select/docs/example.yml +2 -0
  9. data/app/pb_kits/playbook/pb_multi_level_select/docs/index.js +1 -0
  10. data/app/pb_kits/playbook/pb_multi_level_select/multi_level_select.html.erb +1 -1
  11. data/app/pb_kits/playbook/pb_multi_level_select/multi_level_select.rb +3 -0
  12. data/app/pb_kits/playbook/pb_multiple_users/{_multiple_users.jsx → _multiple_users.tsx} +8 -7
  13. data/app/pb_kits/playbook/pb_multiple_users/multiple_users.test.js +52 -0
  14. data/app/pb_kits/playbook/pb_multiple_users_stacked/_multiple_users_stacked.test.js +61 -0
  15. data/app/pb_kits/playbook/pb_multiple_users_stacked/{_multiple_users_stacked.jsx → _multiple_users_stacked.tsx} +22 -25
  16. data/app/pb_kits/playbook/pb_progress_pills/{_progress_pills.jsx → _progress_pills.tsx} +23 -28
  17. data/app/pb_kits/playbook/pb_progress_pills/docs/_progress_pills_default.jsx +11 -12
  18. data/app/pb_kits/playbook/pb_progress_pills/docs/_progress_pills_status.jsx +13 -14
  19. data/app/pb_kits/playbook/pb_progress_pills/progress_pills.test.js +54 -0
  20. data/app/pb_kits/playbook/pb_progress_step/{_progress_step.jsx → _progress_step.tsx} +15 -7
  21. data/app/pb_kits/playbook/pb_progress_step/{_progress_step_item.jsx → _progress_step_item.tsx} +18 -11
  22. data/app/pb_kits/playbook/pb_progress_step/docs/_progress_step_default.jsx +2 -2
  23. data/app/pb_kits/playbook/pb_progress_step/docs/_progress_step_tracker.jsx +1 -1
  24. data/app/pb_kits/playbook/pb_progress_step/docs/_progress_step_tracker_click_events.jsx +1 -1
  25. data/app/pb_kits/playbook/pb_progress_step/docs/_progress_step_vertical.jsx +2 -2
  26. data/app/pb_kits/playbook/pb_progress_step/progress_step.test.js +109 -0
  27. data/lib/playbook/version.rb +2 -2
  28. metadata +19 -12
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2d163824bfc8bd3c476dba23afdaf149ff693c576f3770ab1bcf23637ef32642
4
- data.tar.gz: 272fb5d4927e1a8d4a910f705bc3df87c5d5a7d51faa401b0b26820dfe76180b
3
+ metadata.gz: 0754b3a864404fcaf46b40703c33a6507b0964d9f64b7b8e7557d9846b297aba
4
+ data.tar.gz: edb037066952b45d0768a3c59d3aca3a008a937a741bf82ff37d5950f06d679f
5
5
  SHA512:
6
- metadata.gz: 57e8eb9c7d6f7af39f4dee6e573576107107294c40635a14982027bef2acb2c292a440e3f3a0f7719aff2c5618aa2cb77f20fc5d0338bc1ccdec0603292ccfe5
7
- data.tar.gz: 4ea238e7ebbb4461f48446ab78d95e012dfb48b49339268fc9aefb97bc75ce9c6cb72bb9b080885e90500616739d2ac10ade7e5bb6faa696a18aa9ba8fc344c9
6
+ metadata.gz: af949289757a115a26081aa1aee68f791584150523e59499c97092a4c80269a1f41234ea7c7022294661cc079efb442a58f37bd65c06aa0a94d3a1cf3cfcf120
7
+ data.tar.gz: b8ae58b94e8d6027297420f4bdf90fc8a6586516a87540b94f6fffd5ca7fe613df2f31012bff008b730868eff336950afe41a2ed3b35b7cfd535f6f87405e96b
@@ -14,8 +14,8 @@ type AvatarProps = {
14
14
  dark?: boolean,
15
15
  id?: string,
16
16
  imageAlt?: string,
17
- imageUrl: string,
18
- name: string,
17
+ imageUrl?: string,
18
+ name?: string,
19
19
  size?: "md" | "lg" | "sm" | "xl" | "xs" | "xxs",
20
20
  status?: "away" | "offline" | "online",
21
21
  } & GlobalProps
@@ -1,4 +1,4 @@
1
- import React, { useState, useEffect } from "react";
1
+ import React, { useState, useEffect, useMemo } from "react";
2
2
  import classnames from "classnames";
3
3
  import { buildAriaProps, buildCss, buildDataProps } from "../utilities/props";
4
4
  import { globalProps } from "../utilities/globalProps";
@@ -10,8 +10,8 @@ type MultiLevelSelectProps = {
10
10
  className?: string;
11
11
  data?: { [key: string]: string };
12
12
  id?: string;
13
+ returnAllSelected?: boolean;
13
14
  treeData?: { [key: string]: string }[];
14
- onChange?: any;
15
15
  onSelect?: (prop: { [key: string]: any }) => void;
16
16
  };
17
17
 
@@ -21,6 +21,7 @@ const MultiLevelSelect = (props: MultiLevelSelectProps) => {
21
21
  className,
22
22
  data = {},
23
23
  id,
24
+ returnAllSelected = false,
24
25
  treeData,
25
26
  onSelect = () => {},
26
27
  } = props;
@@ -63,34 +64,59 @@ const MultiLevelSelect = (props: MultiLevelSelectProps) => {
63
64
  };
64
65
 
65
66
  useEffect(() => {
66
- const selected = selectedItems.filter(
67
- (item: { [key: string]: any }) => item.checked
68
- );
69
- //filter to remove duplicate items
70
- const uniqueSelected = selected.filter(
71
- (obj, index, self) => index === self.findIndex((t) => t.id === obj.id)
72
- );
73
- setCheckedData(uniqueSelected);
67
+ if (returnAllSelected) {
68
+ const selected = selectedItems.filter(
69
+ (item: { [key: string]: any }) => item.checked
70
+ );
71
+ //filter to remove duplicate items
72
+ const uniqueSelected = selected.filter(
73
+ (obj, index, self) => index === self.findIndex((t) => t.id === obj.id)
74
+ );
75
+ setCheckedData(uniqueSelected);
76
+ }
74
77
  }, [selectedItems]);
75
78
 
76
79
  useEffect(() => {
77
- let el = document.getElementById("pb_data_wrapper");
78
-
80
+ let el = document.getElementById(`pb_data_wrapper_${id}`);
79
81
  if (el) {
80
82
  el.setAttribute("data-tree", JSON.stringify(checkedData));
81
83
  }
82
-
83
- onSelect(checkedData);
84
+ if (returnAllSelected) {
85
+ onSelect(checkedData);
86
+ }
84
87
  }, [checkedData]);
85
88
 
86
- return (
87
- <div {...ariaProps} {...dataProps} className={classes} id={id}>
89
+ const DropDownSelectComponent = useMemo(() => {
90
+ return (
88
91
  <MultiSelectHelper
89
92
  treeData={formattedData}
93
+ onChange={(
94
+ // @ts-ignore
95
+ selectedNodes: { [key: string]: any }[],
96
+ currentNode: { [key: string]: any }[]
97
+ ) => {
98
+ setCheckedData(currentNode);
99
+ onSelect(currentNode);
100
+ }}
90
101
  id={id}
91
- onChange={onChange}
92
102
  {...props}
93
103
  />
104
+ );
105
+ }, [formattedData]);
106
+
107
+ return (
108
+ <div {...ariaProps} {...dataProps} className={classes} id={id}>
109
+ {returnAllSelected ? (
110
+ <MultiSelectHelper
111
+ treeData={formattedData}
112
+ treeMode={returnAllSelected}
113
+ id={id}
114
+ onChange={onChange}
115
+ {...props}
116
+ />
117
+ ) : (
118
+ <>{DropDownSelectComponent}</>
119
+ )}
94
120
  </div>
95
121
  );
96
122
  };
@@ -5,12 +5,13 @@ import "react-dropdown-tree-select/dist/styles.css"
5
5
  type HelperProps = {
6
6
  id?: string
7
7
  treeData?: { [key: string]: string }[]
8
- onChange?: () => {}
8
+ treeMode?: boolean
9
+ onChange?: any
9
10
 
10
11
  }
11
12
 
12
13
  const MultiSelectHelper = (props: HelperProps) => {
13
- const { id, treeData, onChange } = props
14
+ const { id, treeData, onChange, treeMode } = props
14
15
 
15
16
 
16
17
  return (
@@ -22,7 +23,7 @@ const MultiSelectHelper = (props: HelperProps) => {
22
23
  keepChildrenOnSearch
23
24
  onChange={onChange}
24
25
  texts={{ placeholder: "Select..." }}
25
- mode='hierarchical'
26
+ mode={treeMode ? 'hierarchical' : 'multiSelect'}
26
27
  />
27
28
  )
28
29
  }
@@ -0,0 +1,71 @@
1
+ <% treeData = [{
2
+ label: "Power Home Remodeling",
3
+ value: "Power Home Remodeling",
4
+ id: "powerhome1",
5
+ expanded: true,
6
+ children: [
7
+ {
8
+ label: "People",
9
+ value: "People",
10
+ id: "people1",
11
+ children: [
12
+ {
13
+ label: "Talent Acquisition",
14
+ value: "Talent Acquisition",
15
+ id: "talent1",
16
+ },
17
+ {
18
+ label: "Business Affairs",
19
+ value: "Business Affairs",
20
+ id: "business1",
21
+ children: [
22
+ {
23
+ label: "Initiatives",
24
+ value: "Initiatives",
25
+ id: "initiative1",
26
+ },
27
+ {
28
+ label: "Learning & Development",
29
+ value: "Learning & Development",
30
+ id: "development1",
31
+ },
32
+ ],
33
+ },
34
+ {
35
+ label: "People Experience",
36
+ value: "People Experience",
37
+ id: "experience1",
38
+ },
39
+ ],
40
+ },
41
+ {
42
+ label: "Contact Center",
43
+ value: "Contact Center",
44
+ id: "contact1",
45
+ children: [
46
+ {
47
+ label: "Appointment Management",
48
+ value: "Appointment Management",
49
+ id: "appointment1",
50
+ },
51
+ {
52
+ label: "Customer Service",
53
+ value: "Customer Service",
54
+ id: "customer1",
55
+ },
56
+ {
57
+ label: "Energy",
58
+ value: "Energy",
59
+ id: "energy1",
60
+ },
61
+ ],
62
+ },
63
+ ],
64
+ }] %>
65
+
66
+
67
+ <%= pb_rails("multi_level_select", props: {
68
+ id: "parent-persistence-multi-level-select",
69
+ tree_data:treeData,
70
+ return_all_selected: true
71
+ }) %>
@@ -0,0 +1,87 @@
1
+ import React from "react";
2
+ import MultiLevelSelect from "../_multi_level_select";
3
+
4
+ const treeData = [
5
+ {
6
+ label: "Power Home Remodeling",
7
+ value: "Power Home Remodeling",
8
+ id: "powerhome1",
9
+ expanded: true,
10
+ children: [
11
+ {
12
+ label: "People",
13
+ value: "People",
14
+ id: "people1",
15
+ children: [
16
+ {
17
+ label: "Talent Acquisition",
18
+ value: "Talent Acquisition",
19
+ id: "talent1",
20
+ },
21
+ {
22
+ label: "Business Affairs",
23
+ value: "Business Affairs",
24
+ id: "business1",
25
+ children: [
26
+ {
27
+ label: "Initiatives",
28
+ value: "Initiatives",
29
+ id: "initiative1",
30
+ },
31
+ {
32
+ label: "Learning & Development",
33
+ value: "Learning & Development",
34
+ id: "development1",
35
+ },
36
+ ],
37
+ },
38
+ {
39
+ label: "People Experience",
40
+ value: "People Experience",
41
+ id: "experience1",
42
+ },
43
+ ],
44
+ },
45
+ {
46
+ label: "Contact Center",
47
+ value: "Contact Center",
48
+ id: "contact1",
49
+ children: [
50
+ {
51
+ label: "Appointment Management",
52
+ value: "Appointment Management",
53
+ id: "appointment1",
54
+ },
55
+ {
56
+ label: "Customer Service",
57
+ value: "Customer Service",
58
+ id: "customer1",
59
+ },
60
+ {
61
+ label: "Energy",
62
+ value: "Energy",
63
+ id: "energy1",
64
+ },
65
+ ],
66
+ },
67
+ ],
68
+ },
69
+ ];
70
+
71
+ const MultiLevelSelectReturnAllSelected = (props) => {
72
+ return (
73
+ <div>
74
+ <MultiLevelSelect
75
+ id="multiselect-parent-persistence"
76
+ onSelect={(selectedNodes) =>
77
+ console.log("Selected Items", selectedNodes)
78
+ }
79
+ returnAllSelected
80
+ treeData={treeData}
81
+ {...props}
82
+ />
83
+ </div>
84
+ );
85
+ };
86
+
87
+ export default MultiLevelSelectReturnAllSelected;
@@ -0,0 +1,3 @@
1
+ The `returnAllSelected` or `return_all_selected` prop can be used when users want data on all checked nodes from the dropdown, irrespective of whether it is a parent or child node.
2
+
3
+ __NOTE__ :This variant also does not automatically uncheck the parent when any of the child nodes are unchecked. `returnAllSelected` is set to false by default.
@@ -1,7 +1,9 @@
1
1
  examples:
2
2
  rails:
3
3
  - multi_level_select_default: Default
4
+ - multi_level_select_return_all_selected: Return All Selected
4
5
 
5
6
  react:
6
7
  - multi_level_select_default: Default
8
+ - multi_level_select_return_all_selected: Return All Selected
7
9
 
@@ -1 +1,2 @@
1
1
  export { default as MultiLevelSelectDefault } from './_multi_level_select_default.jsx'
2
+ export { default as MultiLevelSelectReturnAllSelected } from './_multi_level_select_return_all_selected.jsx'
@@ -1,3 +1,3 @@
1
- <div id="pb_data_wrapper" data-tree="">
1
+ <div id="pb_data_wrapper_<%= object.id %>" data-tree="">
2
2
  <%= react_component("MultiLevelSelect", object.multi_level_select_options ) %>
3
3
  </div>
@@ -5,6 +5,8 @@ module Playbook
5
5
  class MultiLevelSelect < Playbook::KitBase
6
6
  prop :tree_data, type: Playbook::Props::Array,
7
7
  default: []
8
+ prop :return_all_selected, type: Playbook::Props::Boolean,
9
+ default: false
8
10
 
9
11
  def classname
10
12
  generate_classname("pb_multi_level_select")
@@ -14,6 +16,7 @@ module Playbook
14
16
  {
15
17
  id: id,
16
18
  treeData: tree_data,
19
+ returnAllSelected: return_all_selected,
17
20
  }
18
21
  end
19
22
  end
@@ -9,18 +9,18 @@ import { globalProps } from '../utilities/globalProps'
9
9
  import Avatar from '../pb_avatar/_avatar'
10
10
 
11
11
  type MultipleUsersProps = {
12
- aria?: object,
12
+ aria?: { [key: string]: string },
13
13
  className?: string,
14
14
  dark?: boolean,
15
- data?: object,
15
+ data?: { [key: string]: string },
16
16
  id?: string,
17
17
  maxDisplayedUsers?: number,
18
18
  reverse?: boolean,
19
- size?: string,
20
- users: array<object>,
19
+ size?: "md" | "lg" | "sm" | "xl" | "xs" | "xxs",
20
+ users: Array<{ [key: string]: string }>,
21
21
  }
22
22
 
23
- const MultipleUsers = (props: MultipleUsersProps) => {
23
+ const MultipleUsers = (props: MultipleUsersProps): React.ReactElement => {
24
24
  const {
25
25
  aria = {},
26
26
  className,
@@ -64,16 +64,17 @@ const MultipleUsers = (props: MultipleUsersProps) => {
64
64
  {...avatarData}
65
65
  className="pb_multiple_users_item"
66
66
  dark={dark}
67
+ imageAlt={avatarData.name}
67
68
  key={index}
68
69
  size={size}
69
70
  />
70
71
  ))}
71
72
 
72
- <If condition={users.length > maxDisplayedUsers}>
73
+ { users.length > maxDisplayedUsers &&
73
74
  <div className={itemClasses}>
74
75
  {`+${users.length - 3}`}
75
76
  </div>
76
- </If>
77
+ }
77
78
  </div>
78
79
  )
79
80
  }
@@ -0,0 +1,52 @@
1
+ import React from 'react'
2
+ import { render, screen } from '../utilities/test-utils'
3
+
4
+ import MultipleUsers from './_multiple_users'
5
+
6
+ const testId = 'multipleUserId'
7
+
8
+ const MultipleUsersTest = () => {
9
+ return (
10
+ <>
11
+ <MultipleUsers
12
+ aria={{ label: testId }}
13
+ className={'custom-class'}
14
+ data={{ testid: testId }}
15
+ users={[
16
+ {
17
+ name: 'Patrick Welch',
18
+ imageUrl: 'https://randomuser.me/api/portraits/men/9.jpg',
19
+ },
20
+ {
21
+ name: 'Lucille Sanchez',
22
+ imageUrl: 'https://randomuser.me/api/portraits/women/6.jpg',
23
+ },
24
+ ]}
25
+ />
26
+ </>
27
+ )
28
+ }
29
+
30
+ test('it loads the given images urls', () => {
31
+ render(<MultipleUsersTest/>)
32
+
33
+ const image1 = screen.getByAltText('Patrick Welch')
34
+ const image2 = screen.getByAltText('Lucille Sanchez')
35
+
36
+ expect(image1).toHaveAttribute('src', 'https://randomuser.me/api/portraits/men/9.jpg')
37
+ expect(image2).toHaveAttribute('src', 'https://randomuser.me/api/portraits/women/6.jpg')
38
+ })
39
+
40
+ test('should render custom class and data', () => {
41
+ render(<MultipleUsersTest/>)
42
+
43
+ const kit = screen.getByTestId(testId)
44
+ expect(kit).toHaveClass('custom-class')
45
+ })
46
+
47
+ test('should render aria-label', () => {
48
+ render(<MultipleUsersTest />)
49
+
50
+ const kit = screen.getByTestId(testId)
51
+ expect(kit).toHaveAttribute('aria-label', testId)
52
+ })
@@ -0,0 +1,61 @@
1
+ import React from 'react'
2
+ import { render, screen } from '../utilities/test-utils'
3
+
4
+ import MultipleUsersStacked from './_multiple_users_stacked'
5
+
6
+ const testId = 'multipleUsersStacked'
7
+ const className = 'custom-class-name'
8
+ const nameUser1 = 'Patrick Welch'
9
+ const nameUser2 = 'Lucille Sanchez'
10
+ const imageUser1 = 'https://randomuser.me/api/portraits/men/9.jpg'
11
+ const imageUser2 = 'https://randomuser.me/api/portraits/women/6.jpg'
12
+
13
+ const MultipleUsersStackedDefault = () => {
14
+ return (
15
+ <MultipleUsersStacked
16
+ aria={{ label: testId }}
17
+ className={className}
18
+ data={{ testid: testId }}
19
+ users={[
20
+ {
21
+ name: nameUser1,
22
+ imageUrl: imageUser1,
23
+ imageAlt: nameUser1,
24
+ },
25
+ {
26
+ name: nameUser2,
27
+ imageUrl: imageUser2,
28
+ imageAlt: nameUser2,
29
+ },
30
+ ]}
31
+ />
32
+ )
33
+ }
34
+
35
+ test('should render alt names and images', () => {
36
+ render(<MultipleUsersStackedDefault />)
37
+
38
+ const image1 = screen.getByAltText(nameUser1)
39
+ const image2 = screen.getByAltText(nameUser2)
40
+
41
+ expect(image1).toHaveAttribute('src', imageUser1)
42
+ expect(image2).toHaveAttribute('src', imageUser2)
43
+ })
44
+
45
+ test('should pass data prop', () => {
46
+ render(<MultipleUsersStackedDefault />)
47
+ const kit = screen.getByTestId(testId)
48
+ expect(kit).toBeInTheDocument()
49
+ })
50
+
51
+ test('should pass className prop', () => {
52
+ render(<MultipleUsersStackedDefault />)
53
+ const kit = screen.getByTestId(testId)
54
+ expect(kit).toHaveClass(className)
55
+ })
56
+
57
+ test('should pass aria prop', () => {
58
+ render(<MultipleUsersStackedDefault />)
59
+ const kit = screen.getByTestId(testId)
60
+ expect(kit).toHaveAttribute('aria-label', testId)
61
+ })
@@ -1,6 +1,3 @@
1
- /* @flow */
2
- /*eslint-disable react/no-multi-comp, flowtype/space-before-type-colon */
3
-
4
1
  import React from 'react'
5
2
  import classnames from 'classnames'
6
3
 
@@ -11,12 +8,12 @@ import Avatar from '../pb_avatar/_avatar'
11
8
  import Badge from '../pb_badge/_badge'
12
9
 
13
10
  type MultipleUsersStackedProps = {
14
- aria?: object,
11
+ aria?: { [key: string]: string },
15
12
  className?: string,
16
13
  dark?: boolean,
17
- data?: object,
14
+ data?: { [key: string]: string },
18
15
  id?: string,
19
- users: array<object>,
16
+ users: Array<{ [key: string]: string }>,
20
17
  }
21
18
 
22
19
  const MultipleUsersStacked = (props: MultipleUsersStackedProps) => {
@@ -44,11 +41,11 @@ const MultipleUsersStacked = (props: MultipleUsersStackedProps) => {
44
41
  return users.slice(0, 1).map((userObject, index) => {
45
42
  return (
46
43
  <Avatar
47
- {...userObject}
48
- className="pb_multiple_users_stacked_item"
49
- dark={dark}
50
- key={index}
51
- size="xs"
44
+ {...userObject}
45
+ className="pb_multiple_users_stacked_item"
46
+ dark={dark}
47
+ key={index}
48
+ size="xs"
52
49
  />
53
50
  )
54
51
  })
@@ -59,11 +56,11 @@ const MultipleUsersStacked = (props: MultipleUsersStackedProps) => {
59
56
  return users.slice(1, 2).map((userObject, index) => {
60
57
  return (
61
58
  <Avatar
62
- {...userObject}
63
- className="pb_multiple_users_stacked_item second_item"
64
- dark={dark}
65
- key={index}
66
- size="xs"
59
+ {...userObject}
60
+ className="pb_multiple_users_stacked_item second_item"
61
+ dark={dark}
62
+ key={index}
63
+ size="xs"
67
64
  />
68
65
  )
69
66
  })
@@ -74,11 +71,11 @@ const MultipleUsersStacked = (props: MultipleUsersStackedProps) => {
74
71
  if (moreThanTwo === true) {
75
72
  return (
76
73
  <Badge
77
- className="pb_multiple_users_stacked_item second_item"
78
- dark={dark}
79
- rounded
80
- text={`+${users.length - displayCount()}`}
81
- variant="primary"
74
+ className="pb_multiple_users_stacked_item second_item"
75
+ dark={dark}
76
+ rounded
77
+ text={`+${users.length - displayCount()}`}
78
+ variant="primary"
82
79
  />
83
80
  )
84
81
  }
@@ -86,10 +83,10 @@ const MultipleUsersStacked = (props: MultipleUsersStackedProps) => {
86
83
 
87
84
  return (
88
85
  <div
89
- {...ariaProps}
90
- {...dataProps}
91
- className={classes}
92
- id={id}
86
+ {...ariaProps}
87
+ {...dataProps}
88
+ className={classes}
89
+ id={id}
93
90
  >
94
91
  {firstUser()}
95
92
  {secondUser()}
@@ -1,5 +1,3 @@
1
- /* @flow */
2
-
3
1
  import React from 'react'
4
2
  import classnames from 'classnames'
5
3
 
@@ -11,39 +9,38 @@ import Title from '../pb_title/_title'
11
9
 
12
10
  type ProgressPillsProps = {
13
11
  active?: number,
14
- aria?: object,
12
+ aria?: {[key: string]: string},
15
13
  className?: string,
16
- data?: object,
14
+ data?: { [key: string]: string },
15
+ dark?: boolean,
17
16
  id?: string,
18
17
  steps?: number,
19
18
  title?: string,
20
19
  value?: string,
21
- dark?: boolean,
22
20
  }
23
21
 
24
- const showSteps = (steps, active, dark) => {
22
+ const showSteps = (steps: number, active: number, dark: boolean) => {
25
23
  const items = []
26
24
 
27
25
  for (let step = 1; step <= steps; step++) {
28
- items.push(ProgressPill({ step, active, dark }))
26
+ items.push(ProgressPill({ steps: step, active, dark }))
29
27
  }
30
28
 
31
29
  return items
32
30
  }
33
31
 
34
- const ProgressPill = ({ active, dark, step }: ProgressPillProps) => (
32
+ const ProgressPill = ({ active, dark, steps: step }: ProgressPillsProps) => (
35
33
  <div
36
- className={`pb_progress_pill${step <= active ? '_active' : '_inactive'}${
37
- dark ? ' dark' : ''
38
- }`}
39
- key={step}
34
+ className={`pb_progress_pill${step <= active ? '_active' : '_inactive'}${dark ? ' dark' : ''
35
+ }`}
36
+ key={step}
40
37
  />
41
38
  )
42
39
 
43
40
  const ProgressPills = (props: ProgressPillsProps) => {
44
41
  const {
45
42
  active = 0,
46
- aria = { hidden: true },
43
+ aria = { hidden: 'true' },
47
44
  className,
48
45
  data = {},
49
46
  id,
@@ -59,27 +56,25 @@ const ProgressPills = (props: ProgressPillsProps) => {
59
56
 
60
57
  return (
61
58
  <div
62
- {...ariaProps}
63
- {...dataProps}
64
- className={classes}
65
- id={id}
59
+ {...ariaProps}
60
+ {...dataProps}
61
+ className={classes}
62
+ id={id}
66
63
  >
67
-
68
- <If condition={title}>
64
+ {title &&
69
65
  <div className="progress_pills_status">
70
66
  <Title
71
- dark={dark}
72
- size={4}
73
- tag="h4"
74
- text={title}
67
+ dark={dark}
68
+ size={4}
69
+ tag="h4"
70
+ text={title}
75
71
  />
76
72
  <Body
77
- color="light"
78
- dark={dark}
79
- text={value}
73
+ color="light"
74
+ dark={dark}
75
+ text={value}
80
76
  />
81
- </div>
82
- </If>
77
+ </div>}
83
78
  <div className="progress_pills">{showSteps(steps, active, dark)}</div>
84
79
  </div>
85
80
  )
@@ -1,18 +1,17 @@
1
-
2
1
  import React from 'react'
3
- import ProgressPills from '../_progress_pills.jsx'
2
+ import ProgressPills from '../_progress_pills'
4
3
 
5
4
  const ProgressPillsDefault = (props) => {
6
- return (
7
- <div>
8
- <ProgressPills
9
- active={2}
10
- aria={{ label: '2 out of 3 steps complete' }}
11
- steps={3}
12
- {...props}
13
- />
14
- </div>
15
- )
5
+ return (
6
+ <>
7
+ <ProgressPills
8
+ active={2}
9
+ aria={{ label: '2 out of 3 steps complete' }}
10
+ steps={3}
11
+ {...props}
12
+ />
13
+ </>
14
+ )
16
15
  }
17
16
 
18
17
  export default ProgressPillsDefault
@@ -1,20 +1,19 @@
1
-
2
1
  import React from 'react'
3
- import ProgressPills from '../_progress_pills.jsx'
2
+ import ProgressPills from '../_progress_pills'
4
3
 
5
4
  const ProgressPillsStatus = (props) => {
6
- return (
7
- <div>
8
- <ProgressPills
9
- active={2}
10
- aria={{ label: '2 out of 3 steps complete' }}
11
- steps={3}
12
- title="Status:"
13
- value="Orientation"
14
- {...props}
15
- />
16
- </div>
17
- )
5
+ return (
6
+ <>
7
+ <ProgressPills
8
+ active={2}
9
+ aria={{ label: '2 out of 3 steps complete' }}
10
+ steps={3}
11
+ title="Status:"
12
+ value="Orientation"
13
+ {...props}
14
+ />
15
+ </>
16
+ )
18
17
  }
19
18
 
20
19
  export default ProgressPillsStatus
@@ -0,0 +1,54 @@
1
+ import React from 'react'
2
+ import { render, screen } from '../utilities/test-utils'
3
+
4
+ import ProgressPills from './_progress_pills'
5
+
6
+ const testId = 'progressPills'
7
+ const className = 'custom-class-name'
8
+ const ariaLabel = '2 out of 3 steps complete'
9
+ const title = 'Status:'
10
+ const value = 'Orientation'
11
+
12
+ const ProgressPillsDefault = () => {
13
+ return (
14
+ <ProgressPills
15
+ active={2}
16
+ aria={{ label: ariaLabel }}
17
+ className={className}
18
+ data={{ testid: testId }}
19
+ steps={3}
20
+ title={title}
21
+ value={value}
22
+ />
23
+ )
24
+ }
25
+
26
+ test('should pass data prop', () => {
27
+ render(<ProgressPillsDefault />)
28
+ const kit = screen.getByTestId(testId)
29
+ expect(kit).toBeInTheDocument()
30
+ })
31
+
32
+ test('should pass className prop', () => {
33
+ render(<ProgressPillsDefault />)
34
+ const kit = screen.getByTestId(testId)
35
+ expect(kit).toHaveClass(className)
36
+ })
37
+
38
+ test('should pass aria prop', () => {
39
+ render(<ProgressPillsDefault />)
40
+ const kit = screen.getByTestId(testId)
41
+ expect(kit).toHaveAttribute('aria-label', ariaLabel)
42
+ })
43
+
44
+ test('should render title', () => {
45
+ render(<ProgressPillsDefault />)
46
+ const kit = screen.getByText(title)
47
+ expect(kit).toBeInTheDocument()
48
+ })
49
+
50
+ test('should render value', () => {
51
+ render(<ProgressPillsDefault />)
52
+ const kit = screen.getByText(value)
53
+ expect(kit).toBeInTheDocument()
54
+ })
@@ -1,15 +1,14 @@
1
- /* @flow */
2
-
3
1
  import React from 'react'
4
2
  import classnames from 'classnames'
5
- import { buildCss } from '../utilities/props'
3
+ import { buildAriaProps, buildCss, buildDataProps } from '../utilities/props'
6
4
  import { globalProps } from '../utilities/globalProps'
7
5
 
8
6
  type ProgressStepProps = {
7
+ aria?: { [key: string]: string },
9
8
  className?: string,
10
- data?: string,
9
+ data?: { [key: string]: string },
11
10
  id?: string,
12
- children?: array<React.ReactChild>,
11
+ children?: React.ReactChild[] | React.ReactChild,
13
12
  orientation?: "horizontal" | "vertical",
14
13
  icon?: boolean,
15
14
  showIcon?: boolean,
@@ -17,16 +16,21 @@ type ProgressStepProps = {
17
16
  color?: string,
18
17
  }
19
18
 
20
- const ProgressStep = (props: ProgressStepProps) => {
19
+ const ProgressStep = (props: ProgressStepProps): React.ReactElement => {
21
20
  const {
21
+ aria = {},
22
22
  className,
23
23
  children,
24
24
  color,
25
+ data = {},
25
26
  orientation = 'horizontal',
26
27
  icon = false,
27
28
  showIcon = false,
28
29
  variant,
29
30
  } = props
31
+
32
+ const ariaProps = buildAriaProps(aria)
33
+ const dataProps = buildDataProps(data)
30
34
  const iconStyle = icon === true || showIcon === true ? 'icon' : ''
31
35
  const progressStepCss = buildCss(
32
36
  'pb_progress_step_kit',
@@ -37,7 +41,11 @@ const ProgressStep = (props: ProgressStepProps) => {
37
41
  )
38
42
 
39
43
  return (
40
- <ul className={classnames(progressStepCss, globalProps(props), className)}>
44
+ <ul
45
+ {...ariaProps}
46
+ {...dataProps}
47
+ className={classnames(progressStepCss, globalProps(props), className)}
48
+ >
41
49
  {children}
42
50
  </ul>
43
51
  )
@@ -1,29 +1,35 @@
1
- /* @flow */
2
-
3
1
  import React from 'react'
4
2
  import classnames from 'classnames'
5
3
 
6
- import { buildCss } from '../utilities/props'
4
+ import { buildCss, buildDataProps } from '../utilities/props'
7
5
 
8
6
  import Icon from '../pb_icon/_icon'
9
7
 
10
8
  type ProgressStepItemProps = {
11
9
  className?: string,
10
+ data?: { [key: string]: string },
12
11
  status?: "complete" | "active" | "inactive" | "hidden",
13
- children?: React.Node,
12
+ children?: React.ReactChild[] | React.ReactChild,
14
13
  icon?: string,
15
14
  }
16
15
 
17
- const ProgressStepItem = ({
18
- className,
19
- status = 'inactive',
20
- children,
21
- icon = 'check',
22
- }: ProgressStepItemProps) => {
16
+ const ProgressStepItem = (props: ProgressStepItemProps): React.ReactElement => {
17
+ const {
18
+ className,
19
+ data = {},
20
+ status = 'inactive',
21
+ children,
22
+ icon = 'check',
23
+ } = props
24
+
23
25
  const progressStepItem = buildCss('pb_progress_step_item', status)
26
+ const dataProps = buildDataProps(data)
24
27
 
25
28
  return (
26
- <li className={classnames(progressStepItem, className)}>
29
+ <li
30
+ {...dataProps}
31
+ className={classnames(progressStepItem, className)}
32
+ >
27
33
  <div className="box">
28
34
  <div className="circle">
29
35
  <Icon icon={icon} />
@@ -33,4 +39,5 @@ const ProgressStepItem = ({
33
39
  </li>
34
40
  )
35
41
  }
42
+
36
43
  export default ProgressStepItem
@@ -1,7 +1,7 @@
1
1
  import React from 'react'
2
2
 
3
- import ProgressStep from '../_progress_step.jsx'
4
- import ProgressStepItem from '../_progress_step_item.jsx'
3
+ import ProgressStep from '../_progress_step.tsx'
4
+ import ProgressStepItem from '../_progress_step_item.tsx'
5
5
 
6
6
  const ProgressStepDefault = (props) => (
7
7
  <div>
@@ -1,6 +1,6 @@
1
1
  import React from 'react'
2
2
 
3
- import ProgressStep from '../_progress_step.jsx'
3
+ import ProgressStep from '../_progress_step.tsx'
4
4
  import ProgressStepItem from '../_progress_step_item'
5
5
 
6
6
  import Caption from '../../pb_caption/_caption'
@@ -1,6 +1,6 @@
1
1
  import React, { useState } from 'react'
2
2
 
3
- import ProgressStep from '../_progress_step.jsx'
3
+ import ProgressStep from '../_progress_step.tsx'
4
4
  import ProgressStepItem from '../_progress_step_item'
5
5
 
6
6
  import Caption from '../../pb_caption/_caption'
@@ -1,7 +1,7 @@
1
1
  import React from 'react'
2
2
 
3
- import ProgressStep from '../_progress_step.jsx'
4
- import ProgressStepItem from '../_progress_step_item.jsx'
3
+ import ProgressStep from '../_progress_step.tsx'
4
+ import ProgressStepItem from '../_progress_step_item.tsx'
5
5
 
6
6
  const ProgressStepVertical = (props) => (
7
7
  <div>
@@ -0,0 +1,109 @@
1
+ import React from 'react'
2
+ import { render, screen } from '../utilities/test-utils'
3
+
4
+ import ProgressStep from './_progress_step.tsx'
5
+ import ProgressStepItem from './_progress_step_item.tsx'
6
+
7
+ const testId = 'progressStepId'
8
+ const step1Id = 'step1Id'
9
+ const step2Id = 'step2Id'
10
+ const step3Id = 'step3Id'
11
+
12
+ const ProgressStepTest = () => {
13
+ return (
14
+ <>
15
+ <ProgressStep
16
+ aria={{ label: testId }}
17
+ className={'custom-class'}
18
+ data={{ testid: testId }}
19
+ >
20
+ <ProgressStepItem
21
+ data={{ testid: step1Id }}
22
+ status="complete"
23
+ >
24
+ {'Step 1'}
25
+ </ProgressStepItem>
26
+ <ProgressStepItem
27
+ data={{ testid: step2Id }}
28
+ status="active"
29
+ >
30
+ {'Step 2'}
31
+ </ProgressStepItem>
32
+ <ProgressStepItem
33
+ data={{ testid: step3Id }}
34
+ status="inactive"
35
+ >
36
+ {'Step 3'}
37
+ </ProgressStepItem>
38
+ </ProgressStep>
39
+ </>
40
+ )
41
+ }
42
+
43
+ test('should render custom class and data', () => {
44
+ render(<ProgressStepTest/>)
45
+
46
+ const kit = screen.getByTestId(testId)
47
+ expect(kit).toHaveClass('custom-class')
48
+ })
49
+
50
+ test('should render aria-label', () => {
51
+ render(<ProgressStepTest />)
52
+
53
+ const kit = screen.getByTestId(testId)
54
+ expect(kit).toHaveAttribute('aria-label', testId)
55
+ })
56
+
57
+ test('should render the horizontal variant', () => {
58
+ render(<ProgressStepTest />)
59
+
60
+ const kit = screen.getByTestId(testId)
61
+ expect(kit).toHaveClass('pb_progress_step_kit_horizontal')
62
+ })
63
+
64
+ test('should render the vertical variant', () => {
65
+ render(
66
+ <ProgressStep
67
+ aria={{ label: testId }}
68
+ data={{ testid: testId }}
69
+ orientation="vertical"
70
+ >
71
+ <ProgressStepItem status="complete">{'Step 1'}</ProgressStepItem>
72
+ <ProgressStepItem status="active">{'Step 2'}</ProgressStepItem>
73
+ <ProgressStepItem status="inactive">{'Step 3'}</ProgressStepItem>
74
+ </ProgressStep>
75
+ )
76
+
77
+ const kit = screen.getByTestId(testId)
78
+ expect(kit).toHaveClass('pb_progress_step_kit_vertical')
79
+ })
80
+
81
+ test('should render the tracker variant', () => {
82
+ render(
83
+ <ProgressStep
84
+ aria={{ label: testId }}
85
+ data={{ testid: testId }}
86
+ variant="tracker"
87
+ >
88
+ <ProgressStepItem status="complete">{'Step 1'}</ProgressStepItem>
89
+ <ProgressStepItem status="active">{'Step 2'}</ProgressStepItem>
90
+ <ProgressStepItem status="inactive">{'Step 3'}</ProgressStepItem>
91
+ </ProgressStep>
92
+ )
93
+
94
+ const kit = screen.getByTestId(testId)
95
+ expect(kit).toHaveClass('pb_progress_step_kit_horizontal_tracker')
96
+ })
97
+
98
+
99
+ test('should render the children elements', () => {
100
+ render(<ProgressStepTest />)
101
+
102
+ const step1Kit = screen.getByTestId(step1Id)
103
+ const step2Kit = screen.getByTestId(step2Id)
104
+ const step3Kit = screen.getByTestId(step3Id)
105
+
106
+ expect(step1Kit).toHaveClass('pb_progress_step_item_complete')
107
+ expect(step2Kit).toHaveClass('pb_progress_step_item_active')
108
+ expect(step3Kit).toHaveClass('pb_progress_step_item_inactive')
109
+ })
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Playbook
4
- PREVIOUS_VERSION = "12.7.0"
5
- VERSION = "12.7.1"
4
+ PREVIOUS_VERSION = "12.8.0"
5
+ VERSION = "12.8.0.pre.alpha.PLAY645typescriptprogresstep298"
6
6
  end
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: playbook_ui
3
3
  version: !ruby/object:Gem::Version
4
- version: 12.7.1
4
+ version: 12.8.0.pre.alpha.PLAY645typescriptprogresstep298
5
5
  platform: ruby
6
6
  authors:
7
7
  - Power UX
8
8
  - Power Devs
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2023-03-08 00:00:00.000000000 Z
12
+ date: 2023-03-15 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: actionpack
@@ -1425,14 +1425,17 @@ files:
1425
1425
  - app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_default.html.erb
1426
1426
  - app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_default.jsx
1427
1427
  - app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_default.md
1428
+ - app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_return_all_selected.html.erb
1429
+ - app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_return_all_selected.jsx
1430
+ - app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_return_all_selected.md
1428
1431
  - app/pb_kits/playbook/pb_multi_level_select/docs/example.yml
1429
1432
  - app/pb_kits/playbook/pb_multi_level_select/docs/index.js
1430
1433
  - app/pb_kits/playbook/pb_multi_level_select/helper_functions.ts
1431
1434
  - app/pb_kits/playbook/pb_multi_level_select/multi_level_select.html.erb
1432
1435
  - app/pb_kits/playbook/pb_multi_level_select/multi_level_select.rb
1433
1436
  - app/pb_kits/playbook/pb_multi_level_select/multi_level_select.test.jsx
1434
- - app/pb_kits/playbook/pb_multiple_users/_multiple_users.jsx
1435
1437
  - app/pb_kits/playbook/pb_multiple_users/_multiple_users.scss
1438
+ - app/pb_kits/playbook/pb_multiple_users/_multiple_users.tsx
1436
1439
  - app/pb_kits/playbook/pb_multiple_users/docs/_description.md
1437
1440
  - app/pb_kits/playbook/pb_multiple_users/docs/_multiple_users_default.html.erb
1438
1441
  - app/pb_kits/playbook/pb_multiple_users/docs/_multiple_users_default.jsx
@@ -1445,8 +1448,10 @@ files:
1445
1448
  - app/pb_kits/playbook/pb_multiple_users/docs/index.js
1446
1449
  - app/pb_kits/playbook/pb_multiple_users/multiple_users.html.erb
1447
1450
  - app/pb_kits/playbook/pb_multiple_users/multiple_users.rb
1448
- - app/pb_kits/playbook/pb_multiple_users_stacked/_multiple_users_stacked.jsx
1451
+ - app/pb_kits/playbook/pb_multiple_users/multiple_users.test.js
1449
1452
  - app/pb_kits/playbook/pb_multiple_users_stacked/_multiple_users_stacked.scss
1453
+ - app/pb_kits/playbook/pb_multiple_users_stacked/_multiple_users_stacked.test.js
1454
+ - app/pb_kits/playbook/pb_multiple_users_stacked/_multiple_users_stacked.tsx
1450
1455
  - app/pb_kits/playbook/pb_multiple_users_stacked/docs/_description.md
1451
1456
  - app/pb_kits/playbook/pb_multiple_users_stacked/docs/_multiple_users_stacked_default.html.erb
1452
1457
  - app/pb_kits/playbook/pb_multiple_users_stacked/docs/_multiple_users_stacked_default.jsx
@@ -1627,8 +1632,8 @@ files:
1627
1632
  - app/pb_kits/playbook/pb_popover/popover.html.erb
1628
1633
  - app/pb_kits/playbook/pb_popover/popover.rb
1629
1634
  - app/pb_kits/playbook/pb_popover/popover.test.js
1630
- - app/pb_kits/playbook/pb_progress_pills/_progress_pills.jsx
1631
1635
  - app/pb_kits/playbook/pb_progress_pills/_progress_pills.scss
1636
+ - app/pb_kits/playbook/pb_progress_pills/_progress_pills.tsx
1632
1637
  - app/pb_kits/playbook/pb_progress_pills/docs/_description.md
1633
1638
  - app/pb_kits/playbook/pb_progress_pills/docs/_progress_pills_default.html.erb
1634
1639
  - app/pb_kits/playbook/pb_progress_pills/docs/_progress_pills_default.jsx
@@ -1638,6 +1643,7 @@ files:
1638
1643
  - app/pb_kits/playbook/pb_progress_pills/docs/index.js
1639
1644
  - app/pb_kits/playbook/pb_progress_pills/progress_pills.html.erb
1640
1645
  - app/pb_kits/playbook/pb_progress_pills/progress_pills.rb
1646
+ - app/pb_kits/playbook/pb_progress_pills/progress_pills.test.js
1641
1647
  - app/pb_kits/playbook/pb_progress_simple/_progress_simple.scss
1642
1648
  - app/pb_kits/playbook/pb_progress_simple/_progress_simple.tsx
1643
1649
  - app/pb_kits/playbook/pb_progress_simple/docs/_description.md
@@ -1660,9 +1666,9 @@ files:
1660
1666
  - app/pb_kits/playbook/pb_progress_simple/progress_simple.html.erb
1661
1667
  - app/pb_kits/playbook/pb_progress_simple/progress_simple.rb
1662
1668
  - app/pb_kits/playbook/pb_progress_simple/progress_simple.test.js
1663
- - app/pb_kits/playbook/pb_progress_step/_progress_step.jsx
1664
1669
  - app/pb_kits/playbook/pb_progress_step/_progress_step.scss
1665
- - app/pb_kits/playbook/pb_progress_step/_progress_step_item.jsx
1670
+ - app/pb_kits/playbook/pb_progress_step/_progress_step.tsx
1671
+ - app/pb_kits/playbook/pb_progress_step/_progress_step_item.tsx
1666
1672
  - app/pb_kits/playbook/pb_progress_step/docs/_description.md
1667
1673
  - app/pb_kits/playbook/pb_progress_step/docs/_progress_step_custom_icon.html.erb
1668
1674
  - app/pb_kits/playbook/pb_progress_step/docs/_progress_step_default.html.erb
@@ -1677,6 +1683,7 @@ files:
1677
1683
  - app/pb_kits/playbook/pb_progress_step/docs/index.js
1678
1684
  - app/pb_kits/playbook/pb_progress_step/progress_step.html.erb
1679
1685
  - app/pb_kits/playbook/pb_progress_step/progress_step.rb
1686
+ - app/pb_kits/playbook/pb_progress_step/progress_step.test.js
1680
1687
  - app/pb_kits/playbook/pb_progress_step/progress_step_item.html.erb
1681
1688
  - app/pb_kits/playbook/pb_progress_step/progress_step_item.rb
1682
1689
  - app/pb_kits/playbook/pb_radio/_radio.scss
@@ -2437,7 +2444,7 @@ homepage: http://playbook.powerapp.cloud
2437
2444
  licenses:
2438
2445
  - ISC
2439
2446
  metadata: {}
2440
- post_install_message:
2447
+ post_install_message:
2441
2448
  rdoc_options: []
2442
2449
  require_paths:
2443
2450
  - lib
@@ -2448,12 +2455,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
2448
2455
  version: '0'
2449
2456
  required_rubygems_version: !ruby/object:Gem::Requirement
2450
2457
  requirements:
2451
- - - ">="
2458
+ - - ">"
2452
2459
  - !ruby/object:Gem::Version
2453
- version: '0'
2460
+ version: 1.3.1
2454
2461
  requirements: []
2455
2462
  rubygems_version: 3.3.7
2456
- signing_key:
2463
+ signing_key:
2457
2464
  specification_version: 4
2458
2465
  summary: Playbook Design System
2459
2466
  test_files: []