playbook_ui 14.16.0.pre.rc.6 → 14.16.0
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/pb_bar_graph/_bar_graph.tsx +1 -1
- data/app/pb_kits/playbook/pb_circle_chart/_circle_chart.tsx +1 -1
- data/app/pb_kits/playbook/pb_draggable/_draggable.scss +115 -5
- data/app/pb_kits/playbook/pb_draggable/_draggable.tsx +6 -4
- data/app/pb_kits/playbook/pb_draggable/context/index.tsx +35 -9
- data/app/pb_kits/playbook/pb_draggable/context/types.ts +35 -28
- data/app/pb_kits/playbook/pb_draggable/docs/_draggable_drop_zones.jsx +184 -0
- data/app/pb_kits/playbook/pb_draggable/docs/_draggable_drop_zones.md +5 -0
- data/app/pb_kits/playbook/pb_draggable/docs/_draggable_drop_zones_colors.jsx +97 -0
- data/app/pb_kits/playbook/pb_draggable/docs/_draggable_drop_zones_colors.md +1 -0
- data/app/pb_kits/playbook/pb_draggable/subcomponents/DraggableContainer.tsx +11 -2
- data/app/pb_kits/playbook/pb_draggable/subcomponents/DraggableItem.tsx +65 -6
- data/app/pb_kits/playbook/pb_drawer/docs/_drawer_breakpoints.html.erb +3 -0
- data/app/pb_kits/playbook/pb_drawer/docs/example.yml +1 -0
- data/app/pb_kits/playbook/pb_filter/Filter/SortMenu.tsx +2 -1
- data/app/pb_kits/playbook/pb_fixed_confirmation_toast/_fixed_confirmation_toast.scss +2 -2
- data/app/pb_kits/playbook/pb_form/docs/_form_form_with.html.erb +67 -0
- data/app/pb_kits/playbook/pb_form/docs/_form_form_with_validate.html.erb +67 -0
- data/app/pb_kits/playbook/pb_gauge/_gauge.tsx +1 -1
- data/app/pb_kits/playbook/pb_icon/_icon.scss +8 -1
- data/app/pb_kits/playbook/pb_icon/docs/_icon_color.html.erb +10 -4
- data/app/pb_kits/playbook/pb_icon/docs/_icon_color.jsx +49 -24
- data/app/pb_kits/playbook/pb_icon_button/_icon_button.tsx +4 -1
- data/app/pb_kits/playbook/pb_icon_button/docs/_icon_button_click.jsx +13 -0
- data/app/pb_kits/playbook/pb_icon_button/docs/example.yml +1 -0
- data/app/pb_kits/playbook/pb_icon_button/docs/index.js +1 -0
- data/app/pb_kits/playbook/pb_lightbox/Carousel/Slide.tsx +1 -1
- data/app/pb_kits/playbook/pb_lightbox/Carousel/Slides.tsx +1 -1
- data/app/pb_kits/playbook/pb_lightbox/Carousel/Thumbnails.tsx +1 -1
- data/app/pb_kits/playbook/pb_line_graph/_line_graph.tsx +1 -1
- data/app/pb_kits/playbook/pb_multi_level_select/_multi_level_select.scss +23 -0
- data/app/pb_kits/playbook/pb_multi_level_select/_multi_level_select.tsx +26 -0
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_error.html.erb +72 -0
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_error.jsx +97 -0
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_label.html.erb +71 -0
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_label.jsx +91 -0
- data/app/pb_kits/playbook/pb_multi_level_select/docs/example.yml +4 -0
- data/app/pb_kits/playbook/pb_multi_level_select/docs/index.js +3 -1
- data/app/pb_kits/playbook/pb_multi_level_select/index.js +105 -0
- data/app/pb_kits/playbook/pb_multi_level_select/multi_level_select.rb +10 -0
- data/app/pb_kits/playbook/pb_nav/_nav.scss +5 -0
- data/app/pb_kits/playbook/pb_treemap_chart/_treemap_chart.tsx +1 -1
- data/app/pb_kits/playbook/pb_typeahead/_typeahead.scss +4 -0
- data/app/pb_kits/playbook/pb_typeahead/_typeahead.tsx +3 -0
- data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_disabled.html.erb +19 -0
- data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_disabled.jsx +23 -0
- data/app/pb_kits/playbook/pb_typeahead/docs/example.yml +2 -0
- data/app/pb_kits/playbook/pb_typeahead/docs/index.js +1 -0
- data/app/pb_kits/playbook/pb_typeahead/typeahead.rb +3 -0
- data/app/pb_kits/playbook/pb_user/_user.tsx +78 -13
- data/app/pb_kits/playbook/pb_user/docs/_user_font_options.html.erb +22 -0
- data/app/pb_kits/playbook/pb_user/docs/_user_font_options.jsx +40 -0
- data/app/pb_kits/playbook/pb_user/docs/_user_font_options_rails.md +5 -0
- data/app/pb_kits/playbook/pb_user/docs/_user_font_options_react.md +5 -0
- data/app/pb_kits/playbook/pb_user/docs/example.yml +2 -0
- data/app/pb_kits/playbook/pb_user/docs/index.js +1 -0
- data/app/pb_kits/playbook/pb_user/user.html.erb +27 -6
- data/app/pb_kits/playbook/pb_user/user.rb +17 -1
- data/app/pb_kits/playbook/pb_user/user.test.js +182 -1
- data/app/pb_kits/playbook/tokens/_colors.scss +1 -4
- data/app/pb_kits/playbook/utilities/object.test.js +139 -1
- data/app/pb_kits/playbook/utilities/object.ts +86 -0
- data/app/pb_kits/playbook/utilities/text.ts +1 -1
- data/dist/chunks/_typeahead-BuTZG1Jn.js +22 -0
- data/dist/chunks/_weekday_stacked-oT22q75-.js +45 -0
- data/dist/chunks/lazysizes-DHz07jlL.js +1 -0
- data/dist/chunks/{lib-BeKPJYlk.js → lib-Co5y3V4K.js} +2 -2
- data/dist/chunks/{pb_form_validation-BvDxpfs-.js → pb_form_validation-DMajaRt3.js} +1 -1
- data/dist/chunks/vendor.js +1 -1
- data/dist/playbook-doc.js +1 -1
- data/dist/playbook-rails-react-bindings.js +1 -1
- data/dist/playbook-rails.js +1 -1
- data/dist/playbook.css +1 -1
- data/lib/playbook/forms/builder/multi_level_select_field.rb +2 -0
- data/lib/playbook/version.rb +1 -1
- metadata +23 -7
- data/dist/chunks/_typeahead-CRAPc8k-.js +0 -22
- data/dist/chunks/_weekday_stacked-T0kFfioG.js +0 -45
- data/dist/chunks/lazysizes-B7xYodB-.js +0 -1
@@ -7,6 +7,8 @@ import { GlobalProps, globalProps } from '../utilities/globalProps'
|
|
7
7
|
import Avatar from '../pb_avatar/_avatar'
|
8
8
|
import Body from '../pb_body/_body'
|
9
9
|
import Title from '../pb_title/_title'
|
10
|
+
import Caption from '../pb_caption/_caption'
|
11
|
+
import Detail from '../pb_detail/_detail'
|
10
12
|
|
11
13
|
type UserProps = {
|
12
14
|
align?: "left" | "center" | "right",
|
@@ -20,11 +22,13 @@ type UserProps = {
|
|
20
22
|
htmlOptions?: {[key: string]: string | number | boolean | (() => void)},
|
21
23
|
id?: string,
|
22
24
|
name?: string,
|
25
|
+
nameStyle?: "title" | "body" | "caption" | "detail"
|
23
26
|
orientation?: "horizontal" | "vertical",
|
24
27
|
size?: "sm" | "md" | "lg",
|
25
28
|
subtitle?: string | Array<Node> | Node,
|
26
29
|
territory?: string,
|
27
30
|
title?: string,
|
31
|
+
titleStyle?: "title" | "body" | "caption" | "detail",
|
28
32
|
} & GlobalProps
|
29
33
|
|
30
34
|
const User = (props: UserProps): React.ReactElement => {
|
@@ -40,11 +44,13 @@ const User = (props: UserProps): React.ReactElement => {
|
|
40
44
|
htmlOptions = {},
|
41
45
|
id,
|
42
46
|
name,
|
47
|
+
nameStyle = 'title',
|
43
48
|
orientation = 'horizontal',
|
44
49
|
size = 'sm',
|
45
50
|
subtitle,
|
46
51
|
territory = '',
|
47
52
|
title = '',
|
53
|
+
titleStyle = 'body',
|
48
54
|
} = props
|
49
55
|
|
50
56
|
const dataProps: {[key: string]: string} = buildDataProps(data)
|
@@ -58,6 +64,76 @@ const User = (props: UserProps): React.ReactElement => {
|
|
58
64
|
)
|
59
65
|
|
60
66
|
const avatarPresent = avatar || avatarUrl
|
67
|
+
const titleText = territory === '' ? title : `${territory} • ${title}`
|
68
|
+
|
69
|
+
const renderNameComponent = () => {
|
70
|
+
switch (nameStyle) {
|
71
|
+
case "title":
|
72
|
+
return (
|
73
|
+
<Title
|
74
|
+
bold={bold}
|
75
|
+
dark={dark}
|
76
|
+
size={size === "lg" ? 3 : 4}
|
77
|
+
text={name}
|
78
|
+
/>
|
79
|
+
);
|
80
|
+
case "body":
|
81
|
+
return (
|
82
|
+
<Body
|
83
|
+
dark={dark}
|
84
|
+
text={name}
|
85
|
+
/>
|
86
|
+
);
|
87
|
+
case "caption":
|
88
|
+
return (
|
89
|
+
<Caption
|
90
|
+
dark={dark}
|
91
|
+
size={size === "sm" ? "xs" : size}
|
92
|
+
text={name}
|
93
|
+
/>
|
94
|
+
);
|
95
|
+
case "detail":
|
96
|
+
return (
|
97
|
+
<Detail
|
98
|
+
dark={dark}
|
99
|
+
text={name}
|
100
|
+
/>
|
101
|
+
);
|
102
|
+
default:
|
103
|
+
return null;
|
104
|
+
}
|
105
|
+
};
|
106
|
+
|
107
|
+
const renderTitleComponent = () => {
|
108
|
+
switch (titleStyle) {
|
109
|
+
case "body":
|
110
|
+
return (
|
111
|
+
<Body
|
112
|
+
color="light"
|
113
|
+
dark={dark}
|
114
|
+
text={titleText}
|
115
|
+
variant={null}
|
116
|
+
/>
|
117
|
+
);
|
118
|
+
case "caption":
|
119
|
+
return (
|
120
|
+
<Caption
|
121
|
+
dark={dark}
|
122
|
+
size={size === "sm" ? "xs" : size}
|
123
|
+
text={titleText}
|
124
|
+
/>
|
125
|
+
);
|
126
|
+
case "detail":
|
127
|
+
return (
|
128
|
+
<Detail
|
129
|
+
dark={dark}
|
130
|
+
text={titleText}
|
131
|
+
/>
|
132
|
+
);
|
133
|
+
default:
|
134
|
+
return null;
|
135
|
+
}
|
136
|
+
};
|
61
137
|
|
62
138
|
return (
|
63
139
|
<div
|
@@ -76,19 +152,8 @@ const User = (props: UserProps): React.ReactElement => {
|
|
76
152
|
/>
|
77
153
|
}
|
78
154
|
<div className="content_wrapper">
|
79
|
-
|
80
|
-
|
81
|
-
dark={dark}
|
82
|
-
size={size == 'lg' ? 3 : 4}
|
83
|
-
text={name}
|
84
|
-
/>
|
85
|
-
<Body
|
86
|
-
color="light"
|
87
|
-
dark={dark}
|
88
|
-
variant={null}
|
89
|
-
>
|
90
|
-
{territory === '' ? title : `${territory} • ${title}`}
|
91
|
-
</Body>
|
155
|
+
{renderNameComponent()}
|
156
|
+
{renderTitleComponent()}
|
92
157
|
{ typeof(subtitle) === 'string' &&
|
93
158
|
<Body
|
94
159
|
color="light"
|
@@ -0,0 +1,22 @@
|
|
1
|
+
<div class="pb--doc-demo-row">
|
2
|
+
<%= pb_rails("user", props: {
|
3
|
+
align: "left",
|
4
|
+
avatar_url: "https://randomuser.me/api/portraits/women/44.jpg",
|
5
|
+
name: "Anna Black",
|
6
|
+
name_style: "body",
|
7
|
+
orientation: "horizontal",
|
8
|
+
size: "md",
|
9
|
+
territory: "PHL",
|
10
|
+
title: "Remodeling Consultant"
|
11
|
+
}) %>
|
12
|
+
<%= pb_rails("user", props: {
|
13
|
+
align: "left",
|
14
|
+
avatar_url: "https://randomuser.me/api/portraits/women/44.jpg",
|
15
|
+
name: "Anna Black",
|
16
|
+
name_style: "detail",
|
17
|
+
orientation: "horizontal",
|
18
|
+
size: "md",
|
19
|
+
territory: "PHL",
|
20
|
+
title: "Remodeling Consultant"
|
21
|
+
}) %>
|
22
|
+
</div>
|
@@ -0,0 +1,40 @@
|
|
1
|
+
import React from 'react'
|
2
|
+
import { User } from 'playbook-ui'
|
3
|
+
|
4
|
+
const UserFontOptions = (props) => {
|
5
|
+
return (
|
6
|
+
<div>
|
7
|
+
<div className="pb--doc-demo-row">
|
8
|
+
<div>
|
9
|
+
<User
|
10
|
+
align="center"
|
11
|
+
avatarUrl="https://randomuser.me/api/portraits/women/44.jpg"
|
12
|
+
name="Anna Black"
|
13
|
+
nameStyle= "body"
|
14
|
+
orientation="horizontal"
|
15
|
+
size= "md"
|
16
|
+
territory= "PHL"
|
17
|
+
title="Remodeling Consultant"
|
18
|
+
{...props}
|
19
|
+
/>
|
20
|
+
</div>
|
21
|
+
|
22
|
+
<div>
|
23
|
+
<User
|
24
|
+
align="left"
|
25
|
+
avatarUrl="https://randomuser.me/api/portraits/women/44.jpg"
|
26
|
+
name="Anna Black"
|
27
|
+
nameStyle= "detail"
|
28
|
+
orientation="horizontal"
|
29
|
+
size= "md"
|
30
|
+
territory= "PHL"
|
31
|
+
title= "Remodeling Consultant"
|
32
|
+
{...props}
|
33
|
+
/>
|
34
|
+
</div>
|
35
|
+
</div>
|
36
|
+
</div>
|
37
|
+
)
|
38
|
+
}
|
39
|
+
|
40
|
+
export default UserFontOptions
|
@@ -0,0 +1,5 @@
|
|
1
|
+
Passing a `name_style` prop changes the type kit used for the user name. You can choose between `title`, `body`, `caption`, and `detail`. `title` is the default.
|
2
|
+
|
3
|
+
Passing a `title_style` prop changes the type kit used for the user title. You can choose between `body`, `caption`, and `detail`. `body` is the default.
|
4
|
+
|
5
|
+
The size of the `caption` is determined by the `size` prop.
|
@@ -0,0 +1,5 @@
|
|
1
|
+
Passing a `nameStyle` prop changes the type kit used for the user name. You can choose between `title`, `body`, `caption`, and `detail`. `title` is the default.
|
2
|
+
|
3
|
+
Passing a `titleStyle` prop changes the type kit used for the user title. You can choose between `body`, `caption`, and `detail`. `body` is the default.
|
4
|
+
|
5
|
+
The size of the `caption` is determined by the `size` prop.
|
@@ -9,6 +9,7 @@ examples:
|
|
9
9
|
- user_vertical_size: Vertical Size
|
10
10
|
- user_subtitle: Subtitle
|
11
11
|
- user_block_content_subtitle_rails: Block Content Subtitle
|
12
|
+
- user_font_options: Font Options
|
12
13
|
|
13
14
|
react:
|
14
15
|
- user_default: Default
|
@@ -19,6 +20,7 @@ examples:
|
|
19
20
|
- user_vertical_size: Vertical Size
|
20
21
|
- user_subtitle: Subtitle
|
21
22
|
- user_block_content_subtitle_react: Block Content Subtitle
|
23
|
+
- user_font_options: Font Options
|
22
24
|
|
23
25
|
swift:
|
24
26
|
- user_horizontal_swift: Horizontal
|
@@ -6,3 +6,4 @@ export { default as UserSize } from './_user_size.jsx'
|
|
6
6
|
export { default as UserVerticalSize } from './_user_vertical_size.jsx'
|
7
7
|
export { default as UserSubtitle } from './_user_subtitle.jsx'
|
8
8
|
export { default as UserBlockContentSubtitleReact } from './_user_block_content_subtitle_react.jsx'
|
9
|
+
export { default as UserFontOptions } from './_user_font_options.jsx'
|
@@ -12,12 +12,33 @@
|
|
12
12
|
}) %>
|
13
13
|
<% end %>
|
14
14
|
<%= content_tag(:div, class: "content_wrapper") do %>
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
15
|
+
<% case object.name_style %>
|
16
|
+
<% when "title" %>
|
17
|
+
<%= pb_rails("title", props: { text: object.name, size: object.name_size, dark: object.dark, bold: object.bold }) %>
|
18
|
+
<% when "body" %>
|
19
|
+
<%= pb_rails("body", props: { text: object.name, dark: object.dark }) %>
|
20
|
+
<% when "caption" %>
|
21
|
+
<%= pb_rails("caption", props: { text: object.name, dark: object.dark, size: object.name_size }) %>
|
22
|
+
<% when "detail" %>
|
23
|
+
<%= pb_rails("detail", props: { text: object.name, dark: object.dark }) %>
|
24
|
+
<% end %>
|
25
|
+
<% case object.title_style %>
|
26
|
+
<% when "body" %>
|
27
|
+
<%= pb_rails("body", props: {
|
28
|
+
text: "#{object.details}",
|
29
|
+
dark: object.dark,
|
30
|
+
color: "light"
|
31
|
+
}) %>
|
32
|
+
<% when "caption" %>
|
33
|
+
<%= pb_rails("caption", props: {
|
34
|
+
text: "#{object.details}",
|
35
|
+
dark: object.dark,
|
36
|
+
color: "light",
|
37
|
+
size: object.title_size
|
38
|
+
}) %>
|
39
|
+
<% when "detail" %>
|
40
|
+
<%= pb_rails("detail", props: { text: "#{object.details}", dark: object.dark }) %>
|
41
|
+
<% end %>
|
21
42
|
<% if content %>
|
22
43
|
<%= content.presence %>
|
23
44
|
<% else %>
|
@@ -11,6 +11,9 @@ module Playbook
|
|
11
11
|
prop :avatar_url
|
12
12
|
prop :bold, type: Playbook::Props::Boolean, default: true
|
13
13
|
prop :name
|
14
|
+
prop :name_style, type: Playbook::Props::Enum,
|
15
|
+
values: %w[title body caption detail],
|
16
|
+
default: "title"
|
14
17
|
prop :orientation, type: Playbook::Props::Enum,
|
15
18
|
values: %w[vertical horizontal],
|
16
19
|
default: "horizontal"
|
@@ -19,6 +22,9 @@ module Playbook
|
|
19
22
|
default: "sm"
|
20
23
|
prop :subtitle
|
21
24
|
prop :title
|
25
|
+
prop :title_style, type: Playbook::Props::Enum,
|
26
|
+
values: %w[body caption detail],
|
27
|
+
default: "body"
|
22
28
|
prop :territory
|
23
29
|
|
24
30
|
def classname
|
@@ -36,8 +42,18 @@ module Playbook
|
|
36
42
|
end
|
37
43
|
end
|
38
44
|
|
45
|
+
def name_size
|
46
|
+
if name_style == "caption"
|
47
|
+
size == "sm" ? "xs" : size
|
48
|
+
else
|
49
|
+
size == "lg" ? 3 : 4
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
39
53
|
def title_size
|
40
|
-
|
54
|
+
if title_style == "caption"
|
55
|
+
size == "sm" ? "xs" : size
|
56
|
+
end
|
41
57
|
end
|
42
58
|
|
43
59
|
def details
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import React from 'react'
|
2
|
-
import { render, screen } from '../utilities/test-utils'
|
2
|
+
import { render, screen , cleanup} from '../utilities/test-utils'
|
3
3
|
import User from './_user'
|
4
4
|
import Caption from "../pb_caption/_caption"
|
5
5
|
|
@@ -40,3 +40,184 @@ test('bold prop applies correct styling when false', () => {
|
|
40
40
|
|
41
41
|
expect(titleElement).toHaveClass('pb_title_kit_size_4_thin')
|
42
42
|
})
|
43
|
+
|
44
|
+
test('align prop adds desired class', () => {
|
45
|
+
[
|
46
|
+
"left",
|
47
|
+
"center",
|
48
|
+
"right"
|
49
|
+
].forEach((alignProp) => {
|
50
|
+
render(
|
51
|
+
<User
|
52
|
+
align={alignProp}
|
53
|
+
data={{ testid: 'test-user-kit' }}
|
54
|
+
name="Anna Black"
|
55
|
+
/>
|
56
|
+
)
|
57
|
+
const kit = screen.getByTestId('test-user-kit')
|
58
|
+
expect(kit.className).toContain(`pb_user_kit_${alignProp}`)
|
59
|
+
|
60
|
+
cleanup()
|
61
|
+
})
|
62
|
+
})
|
63
|
+
|
64
|
+
test('avatar prop adds default avatar img', () => {
|
65
|
+
render(
|
66
|
+
<User
|
67
|
+
avatar
|
68
|
+
data={{ testid: 'test-user-kit' }}
|
69
|
+
/>
|
70
|
+
)
|
71
|
+
|
72
|
+
const container = screen.getByTestId('test-user-kit')
|
73
|
+
const avatarWrapper = container.querySelector('.avatar_wrapper')
|
74
|
+
|
75
|
+
expect(avatarWrapper).toBeInTheDocument()
|
76
|
+
expect(avatarWrapper).toHaveClass('avatar_wrapper')
|
77
|
+
})
|
78
|
+
|
79
|
+
test('avatarUrl prop adds avatar img', () => {
|
80
|
+
const avatarUrl = 'https://example.com/avatar.jpg'
|
81
|
+
render(
|
82
|
+
<User
|
83
|
+
avatarUrl={avatarUrl}
|
84
|
+
data={{ testid: 'test-user-kit' }}
|
85
|
+
/>
|
86
|
+
)
|
87
|
+
|
88
|
+
const container = screen.getByTestId('test-user-kit')
|
89
|
+
const avatarImg = container.querySelector('img')
|
90
|
+
|
91
|
+
expect(avatarImg).toBeInTheDocument()
|
92
|
+
expect(avatarImg).toHaveAttribute('src', avatarUrl)
|
93
|
+
})
|
94
|
+
|
95
|
+
test('name prop adds name text', () => {
|
96
|
+
const name = 'Anna Black'
|
97
|
+
render(
|
98
|
+
<User
|
99
|
+
data={{ testid: 'test-name' }}
|
100
|
+
name={name}
|
101
|
+
/>
|
102
|
+
)
|
103
|
+
|
104
|
+
const titleElement = screen.getByText(name)
|
105
|
+
expect(titleElement).toBeInTheDocument()
|
106
|
+
})
|
107
|
+
|
108
|
+
test('nameStyle prop changes the typography kit', () => {
|
109
|
+
const name = 'Anna Black'
|
110
|
+
const kitTypes = ['body', 'caption', 'detail']
|
111
|
+
|
112
|
+
kitTypes.forEach((typeKit) => {
|
113
|
+
render(
|
114
|
+
<User
|
115
|
+
data={{ testid: 'test-user-kit' }}
|
116
|
+
name={name}
|
117
|
+
nameStyle={typeKit}
|
118
|
+
/>
|
119
|
+
)
|
120
|
+
|
121
|
+
const container = screen.getByTestId('test-user-kit')
|
122
|
+
const subcomponent = container.querySelector(`[class*="pb_${typeKit}_kit"]`)
|
123
|
+
|
124
|
+
expect(subcomponent).toBeInTheDocument()
|
125
|
+
expect(subcomponent).toHaveTextContent(name)
|
126
|
+
|
127
|
+
cleanup()
|
128
|
+
})
|
129
|
+
})
|
130
|
+
|
131
|
+
test('orientation prop adds desired class', () => {
|
132
|
+
[
|
133
|
+
"horizontal",
|
134
|
+
"vertical"
|
135
|
+
].forEach((orientation) => {
|
136
|
+
render(
|
137
|
+
<User
|
138
|
+
data={{ testid: 'test-user-kit' }}
|
139
|
+
name="Anna Black"
|
140
|
+
orientation={orientation}
|
141
|
+
/>
|
142
|
+
)
|
143
|
+
|
144
|
+
const container = screen.getByTestId('test-user-kit')
|
145
|
+
expect(container.className).toContain(orientation)
|
146
|
+
|
147
|
+
cleanup()
|
148
|
+
})
|
149
|
+
})
|
150
|
+
|
151
|
+
test('size prop adds desired class', () => {
|
152
|
+
[
|
153
|
+
"sm",
|
154
|
+
"md",
|
155
|
+
"lg"
|
156
|
+
].forEach((size) => {
|
157
|
+
render(
|
158
|
+
<User
|
159
|
+
data={{ testid: 'test-user-kit' }}
|
160
|
+
name="Anna Black"
|
161
|
+
size={size}
|
162
|
+
/>
|
163
|
+
)
|
164
|
+
|
165
|
+
const container = screen.getByTestId('test-user-kit')
|
166
|
+
expect(container.className).toContain(size)
|
167
|
+
|
168
|
+
cleanup()
|
169
|
+
})
|
170
|
+
})
|
171
|
+
|
172
|
+
test('title prop adds title text', () => {
|
173
|
+
const title = 'Remodeling Consultant'
|
174
|
+
render(
|
175
|
+
<User
|
176
|
+
data={{ testid: 'test-title' }}
|
177
|
+
name="Anna Black"
|
178
|
+
title={title}
|
179
|
+
/>
|
180
|
+
)
|
181
|
+
|
182
|
+
const titleElement = screen.getByText(title)
|
183
|
+
expect(titleElement).toBeInTheDocument()
|
184
|
+
})
|
185
|
+
|
186
|
+
test('titleStyle prop changes the typography kit', () => {
|
187
|
+
const title = 'Remodeling Consultant'
|
188
|
+
const kitTypes = ['caption', 'detail']
|
189
|
+
|
190
|
+
kitTypes.forEach((typeKit) => {
|
191
|
+
render(
|
192
|
+
<User
|
193
|
+
data={{ testid: 'test-user-kit' }}
|
194
|
+
name="Anna Black"
|
195
|
+
title={title}
|
196
|
+
titleStyle={typeKit}
|
197
|
+
/>
|
198
|
+
)
|
199
|
+
|
200
|
+
const container = screen.getByTestId('test-user-kit')
|
201
|
+
const subcomponent = container.querySelector(`[class*="pb_${typeKit}_kit"]`)
|
202
|
+
|
203
|
+
expect(subcomponent).toBeInTheDocument()
|
204
|
+
expect(subcomponent).toHaveTextContent(title)
|
205
|
+
|
206
|
+
cleanup()
|
207
|
+
})
|
208
|
+
})
|
209
|
+
|
210
|
+
test('territory prop adds territory text', () => {
|
211
|
+
const territory = 'PHI'
|
212
|
+
render(
|
213
|
+
<User
|
214
|
+
data={{ testid: 'test-territory' }}
|
215
|
+
name="Anna Black"
|
216
|
+
territory={territory}
|
217
|
+
title="Remodeling Consultant"
|
218
|
+
/>
|
219
|
+
)
|
220
|
+
|
221
|
+
const titleElement = screen.getByText(`${territory} • Remodeling Consultant`)
|
222
|
+
expect(titleElement).toBeInTheDocument()
|
223
|
+
})
|
@@ -41,8 +41,7 @@ $interface_colors: (
|
|
41
41
|
silver: $silver,
|
42
42
|
slate: $slate,
|
43
43
|
charcoal: $charcoal,
|
44
|
-
black: $black
|
45
|
-
|
44
|
+
black: $black
|
46
45
|
);
|
47
46
|
|
48
47
|
/* Main colors ------------------------*/
|
@@ -205,8 +204,6 @@ $status_colors: (
|
|
205
204
|
primary_secondary: $primary_secondary
|
206
205
|
);
|
207
206
|
|
208
|
-
|
209
|
-
|
210
207
|
$status_color_text: (
|
211
208
|
success: $success,
|
212
209
|
success_sm: $text_lt_success_sm,
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import { isEmpty, get, isString, uniqueId, omitBy } from './object';
|
1
|
+
import { isEmpty, get, isString, uniqueId, omitBy, noop, merge, filter, find, partial } from './object';
|
2
2
|
|
3
3
|
describe('Lodash functions', () => {
|
4
4
|
describe('isEmpty', () => {
|
@@ -96,4 +96,142 @@ describe('Lodash functions', () => {
|
|
96
96
|
expect(objWithSmallValues).toEqual(obj);
|
97
97
|
});
|
98
98
|
});
|
99
|
+
|
100
|
+
describe('noop', () => {
|
101
|
+
test('should do nothing and return undefined', () => {
|
102
|
+
expect(noop()).toBeUndefined();
|
103
|
+
});
|
104
|
+
});
|
105
|
+
|
106
|
+
describe('merge', () => {
|
107
|
+
test('merges two objects correctly', () => {
|
108
|
+
const obj1 = { a: 1, b: { x: 10 } };
|
109
|
+
const obj2 = { b: { y: 20 }, c: 3 };
|
110
|
+
expect(merge(obj1, obj2)).toEqual({ a: 1, b: { x: 10, y: 20 }, c: 3 });
|
111
|
+
});
|
112
|
+
|
113
|
+
test('when keys repeat use last occurrence value', () => {
|
114
|
+
const obj1 = { a: 1 };
|
115
|
+
const obj2 = { b: 2 };
|
116
|
+
const obj3 = { a: 3, c: 4 };
|
117
|
+
expect(merge(obj1, obj2, obj3)).toEqual({ a: 3, b: 2, c: 4 });
|
118
|
+
});
|
119
|
+
|
120
|
+
test('ignores non-object arguments', () => {
|
121
|
+
expect(merge(null, { a: 1 })).toEqual({ a: 1 });
|
122
|
+
expect(merge(undefined, { a: 1 })).toEqual({ a: 1 });
|
123
|
+
});
|
124
|
+
});
|
125
|
+
|
126
|
+
describe('filter', () => {
|
127
|
+
test('filters an array using a function predicate', () => {
|
128
|
+
const arr = [1, 2, 3, 4, 5];
|
129
|
+
const isEven = (n) => n % 2 === 0;
|
130
|
+
expect(filter(arr, isEven)).toEqual([2, 4]);
|
131
|
+
});
|
132
|
+
|
133
|
+
test('filters an array using a string predicate', () => {
|
134
|
+
const arr = [
|
135
|
+
{ active: true, name: 'John' },
|
136
|
+
{ active: false, name: 'Jane' },
|
137
|
+
{ active: true, name: 'Doe' }
|
138
|
+
];
|
139
|
+
expect(filter(arr, 'active')).toEqual([
|
140
|
+
{ active: true, name: 'John' },
|
141
|
+
{ active: true, name: 'Doe' }
|
142
|
+
]);
|
143
|
+
});
|
144
|
+
|
145
|
+
test('filters an array using an array predicate', () => {
|
146
|
+
const arr = [
|
147
|
+
{ type: 'fruit', name: 'apple' },
|
148
|
+
{ type: 'vegetable', name: 'carrot' },
|
149
|
+
{ type: 'fruit', name: 'banana' }
|
150
|
+
];
|
151
|
+
expect(filter(arr, ['type', 'fruit'])).toEqual([
|
152
|
+
{ type: 'fruit', name: 'apple' },
|
153
|
+
{ type: 'fruit', name: 'banana' }
|
154
|
+
]);
|
155
|
+
});
|
156
|
+
|
157
|
+
test('filters an array using an object predicate', () => {
|
158
|
+
const arr = [
|
159
|
+
{ type: 'fruit', name: 'apple', color: 'red' },
|
160
|
+
{ type: 'fruit', name: 'banana', color: 'yellow' },
|
161
|
+
{ type: 'vegetable', name: 'carrot', color: 'orange' }
|
162
|
+
];
|
163
|
+
expect(filter(arr, { type: 'fruit', color: 'red' })).toEqual([
|
164
|
+
{ type: 'fruit', name: 'apple', color: 'red' }
|
165
|
+
]);
|
166
|
+
});
|
167
|
+
});
|
168
|
+
|
169
|
+
describe('find', () => {
|
170
|
+
test('finds an element using a function predicate', () => {
|
171
|
+
const arr = [1, 2, 3, 4, 5];
|
172
|
+
const greaterThanThree = (n) => n > 3;
|
173
|
+
expect(find(arr, greaterThanThree)).toBe(4);
|
174
|
+
});
|
175
|
+
|
176
|
+
test('finds an element using a string predicate', () => {
|
177
|
+
const arr = [
|
178
|
+
{ active: false, name: 'John' },
|
179
|
+
{ active: true, name: 'Jane' },
|
180
|
+
{ active: true, name: 'Doe' }
|
181
|
+
];
|
182
|
+
expect(find(arr, 'active')).toEqual({ active: true, name: 'Jane' });
|
183
|
+
});
|
184
|
+
|
185
|
+
test('finds an element using an array predicate', () => {
|
186
|
+
const arr = [
|
187
|
+
{ type: 'fruit', name: 'apple' },
|
188
|
+
{ type: 'vegetable', name: 'carrot' },
|
189
|
+
{ type: 'fruit', name: 'banana' }
|
190
|
+
];
|
191
|
+
expect(find(arr, ['type', 'vegetable'])).toEqual({ type: 'vegetable', name: 'carrot' });
|
192
|
+
});
|
193
|
+
|
194
|
+
test('finds an element using an object predicate', () => {
|
195
|
+
const arr = [
|
196
|
+
{ type: 'fruit', name: 'apple', color: 'red' },
|
197
|
+
{ type: 'fruit', name: 'banana', color: 'yellow' },
|
198
|
+
{ type: 'vegetable', name: 'carrot', color: 'orange' }
|
199
|
+
];
|
200
|
+
expect(find(arr, { name: 'banana', color: 'yellow' })).toEqual({ type: 'fruit', name: 'banana', color: 'yellow' });
|
201
|
+
});
|
202
|
+
|
203
|
+
test('returns undefined if no element matches', () => {
|
204
|
+
const arr = [{ id: 1 }, { id: 2 }];
|
205
|
+
expect(find(arr, { id: 3 })).toBeUndefined();
|
206
|
+
});
|
207
|
+
});
|
208
|
+
|
209
|
+
describe('partial', () => {
|
210
|
+
function add(a, b, c) {
|
211
|
+
return a + b + c;
|
212
|
+
}
|
213
|
+
|
214
|
+
test('partials arguments without placeholders', () => {
|
215
|
+
const add5 = partial(add, 2, 3);
|
216
|
+
expect(add5(4)).toBe(9);
|
217
|
+
});
|
218
|
+
|
219
|
+
test('partials arguments with placeholders', () => {
|
220
|
+
const addWithPlaceholder = partial(add, partial.placeholder, 3, partial.placeholder);
|
221
|
+
expect(addWithPlaceholder(2, 4)).toBe(9);
|
222
|
+
});
|
223
|
+
|
224
|
+
test('returns correct result when all arguments are pre-filled', () => {
|
225
|
+
const addAll = partial(add, 1, 2, 3);
|
226
|
+
expect(addAll()).toBe(6);
|
227
|
+
});
|
228
|
+
|
229
|
+
test('appends extra arguments when provided', () => {
|
230
|
+
function join(...args) {
|
231
|
+
return args.join('_');
|
232
|
+
}
|
233
|
+
const joinPartial = partial(join, 'a');
|
234
|
+
expect(joinPartial('b', 'c')).toBe('a_b_c');
|
235
|
+
});
|
236
|
+
});
|
99
237
|
});
|