playbook_ui 11.4.0 → 11.5.0.pre.alpha.datepicker1
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/data/menu.yml +0 -13
- data/app/pb_kits/playbook/pb_badge/badge.test.js +80 -0
- data/app/pb_kits/playbook/pb_button/_button.tsx +7 -2
- data/app/pb_kits/playbook/pb_button/_button_mixins.scss +7 -0
- data/app/pb_kits/playbook/pb_button/button.html.erb +11 -0
- data/app/pb_kits/playbook/pb_button/button.rb +3 -0
- data/app/pb_kits/playbook/pb_button/button.test.js +6 -8
- data/app/pb_kits/playbook/pb_button/docs/_button_block_content.html.erb +1 -1
- data/app/pb_kits/playbook/pb_button/docs/_button_block_content.jsx +12 -9
- data/app/pb_kits/playbook/pb_button/docs/_button_block_content.md +1 -0
- data/app/pb_kits/playbook/pb_button/docs/_button_icon_options.html.erb +2 -0
- data/app/pb_kits/playbook/pb_button/docs/_button_icon_options.jsx +23 -0
- data/app/pb_kits/playbook/pb_button/docs/_button_icon_options.md +1 -0
- data/app/pb_kits/playbook/pb_button/docs/example.yml +2 -0
- data/app/pb_kits/playbook/pb_button/docs/index.js +1 -0
- data/app/pb_kits/playbook/pb_date/_date.tsx +1 -1
- data/app/pb_kits/playbook/pb_date_picker/_date_picker.jsx +13 -1
- data/app/pb_kits/playbook/pb_date_picker/_date_picker.scss +24 -19
- data/app/pb_kits/playbook/pb_date_picker/date_picker.html.erb +1 -1
- data/app/pb_kits/playbook/pb_date_picker/date_picker.rb +9 -0
- data/app/pb_kits/playbook/pb_date_picker/date_picker_helper.js +25 -3
- data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_positions.html.erb +44 -0
- data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_positions.jsx +60 -0
- data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_positions.md +9 -0
- data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_positions_element.html.erb +33 -0
- data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_positions_element.jsx +67 -0
- data/app/pb_kits/playbook/pb_date_picker/docs/example.yml +4 -0
- data/app/pb_kits/playbook/pb_date_picker/docs/index.js +2 -0
- data/app/pb_kits/playbook/pb_date_picker/sass_partials/_flatpickr_styles.scss +0 -3
- data/app/pb_kits/playbook/pb_date_picker/sass_partials/_overrides.scss +4 -4
- data/app/pb_kits/playbook/pb_date_range_inline/_date_range_inline.tsx +142 -0
- data/app/pb_kits/playbook/pb_date_range_inline/date_range_inline.test.js +116 -0
- data/app/pb_kits/playbook/pb_date_range_inline/docs/_date_range_inline_default.jsx +1 -1
- data/app/pb_kits/playbook/pb_date_time/{_date_time.jsx → _date_time.tsx} +2 -5
- data/app/pb_kits/playbook/pb_date_time/dateTime.test.js +110 -0
- data/app/pb_kits/playbook/pb_date_time/docs/_date_time_align.jsx +1 -1
- data/app/pb_kits/playbook/pb_date_time/docs/_date_time_default.jsx +1 -1
- data/app/pb_kits/playbook/pb_date_time/docs/_date_time_size.jsx +1 -1
- data/app/pb_kits/playbook/pb_date_year_stacked/{_date_year_stacked.jsx → _date_year_stacked.tsx} +6 -6
- data/app/pb_kits/playbook/pb_date_year_stacked/date_year_stacked.test.js +67 -0
- data/app/pb_kits/playbook/pb_dialog/_dialog.jsx +32 -14
- data/app/pb_kits/playbook/pb_dialog/_dialog.scss +5 -0
- data/app/pb_kits/playbook/pb_dialog/child_kits/_dialog_body.jsx +2 -2
- data/app/pb_kits/playbook/pb_dialog/child_kits/_dialog_footer.jsx +22 -4
- data/app/pb_kits/playbook/pb_dialog/child_kits/_dialog_header.jsx +3 -3
- data/app/pb_kits/playbook/pb_dialog/dialog.test.jsx +79 -17
- data/app/pb_kits/playbook/pb_dialog/docs/_dialog_stacked_alert.jsx +55 -93
- data/app/pb_kits/playbook/pb_dialog/docs/_dialog_status.jsx +79 -42
- data/app/pb_kits/playbook/pb_file_upload/{_file_upload.jsx → _file_upload.tsx} +6 -10
- data/app/pb_kits/playbook/pb_filter/Filter/FilterDouble.jsx +2 -0
- data/app/pb_kits/playbook/pb_filter/Filter/FilterSingle.jsx +2 -0
- data/app/pb_kits/playbook/pb_filter/Filter/FiltersPopover.jsx +2 -2
- data/app/pb_kits/playbook/pb_filter/docs/_filter_min_width.html.erb +1 -0
- data/app/pb_kits/playbook/pb_filter/docs/_filter_placement.html.erb +34 -0
- data/app/pb_kits/playbook/pb_filter/docs/_filter_placement.jsx +66 -0
- data/app/pb_kits/playbook/pb_filter/docs/_filter_placement.md +4 -0
- data/app/pb_kits/playbook/pb_filter/docs/example.yml +2 -0
- data/app/pb_kits/playbook/pb_filter/docs/index.js +1 -0
- data/app/pb_kits/playbook/pb_filter/filter.html.erb +2 -2
- data/app/pb_kits/playbook/pb_filter/filter.rb +3 -0
- data/app/pb_kits/playbook/pb_filter/filter.test.js +76 -0
- data/app/pb_kits/playbook/pb_form_group/{_form_group.jsx → _form_group.tsx} +1 -4
- data/app/pb_kits/playbook/pb_form_group/form_group.test.js +17 -0
- data/app/pb_kits/playbook/pb_hashtag/_hashtag.tsx +10 -1
- data/app/pb_kits/playbook/pb_hashtag/docs/_hashtag_link.html.erb +5 -0
- data/app/pb_kits/playbook/pb_hashtag/docs/_hashtag_link.jsx +26 -0
- data/app/pb_kits/playbook/pb_hashtag/docs/_hashtag_link.md +1 -0
- data/app/pb_kits/playbook/pb_hashtag/docs/example.yml +2 -0
- data/app/pb_kits/playbook/pb_hashtag/docs/index.js +1 -0
- data/app/pb_kits/playbook/pb_hashtag/hashtag.html.erb +1 -1
- data/app/pb_kits/playbook/pb_hashtag/hashtag.rb +6 -0
- data/app/pb_kits/playbook/pb_hashtag/hashtag.test.js +54 -0
- data/app/pb_kits/playbook/pb_home_address_street/_home_address_street.tsx +129 -0
- data/app/pb_kits/playbook/pb_home_address_street/city_emphasis.html.erb +2 -1
- data/app/pb_kits/playbook/pb_home_address_street/city_emphasis.rb +2 -0
- data/app/pb_kits/playbook/pb_home_address_street/docs/_home_address_street_default.jsx +1 -1
- data/app/pb_kits/playbook/pb_home_address_street/docs/_home_address_street_emphasis.jsx +2 -2
- data/app/pb_kits/playbook/pb_home_address_street/docs/_home_address_street_link.html.erb +12 -0
- data/app/pb_kits/playbook/pb_home_address_street/docs/_home_address_street_link.jsx +23 -0
- data/app/pb_kits/playbook/pb_home_address_street/docs/_home_address_street_link.md +1 -0
- data/app/pb_kits/playbook/pb_home_address_street/docs/example.yml +3 -0
- data/app/pb_kits/playbook/pb_home_address_street/docs/index.js +1 -0
- data/app/pb_kits/playbook/pb_home_address_street/home_address_street.rb +4 -0
- data/app/pb_kits/playbook/pb_home_address_street/home_adress_street.test.js +60 -0
- data/app/pb_kits/playbook/pb_home_address_street/street_emphasis.html.erb +2 -1
- data/app/pb_kits/playbook/pb_home_address_street/street_emphasis.rb +4 -1
- data/app/pb_kits/playbook/pb_icon_stat_value/{_icon_stat_value.jsx → _icon_stat_value.tsx} +2 -4
- data/app/pb_kits/playbook/pb_icon_stat_value/icon_stat_value.test.js +154 -0
- data/app/pb_kits/playbook/pb_icon_value/{_icon_value.jsx → _icon_value.tsx} +2 -4
- data/app/pb_kits/playbook/pb_icon_value/icon_value.test.js +77 -0
- data/app/pb_kits/playbook/pb_label_value/_label_value.tsx +123 -0
- data/app/pb_kits/playbook/pb_label_value/label_value.test.js +109 -0
- data/app/pb_kits/playbook/pb_layout/{_layout.jsx → _layout.tsx} +13 -19
- data/app/pb_kits/playbook/pb_layout/layout.test.js +97 -0
- data/app/pb_kits/playbook/pb_lightbox/lightbox.test.jsx +23 -15
- data/app/pb_kits/playbook/pb_popover/popover.rb +1 -1
- data/app/pb_kits/playbook/pb_text_input/_text_input.tsx +0 -1
- data/app/pb_kits/playbook/pb_time/_time.tsx +2 -2
- data/app/pb_kits/playbook/pb_timestamp/_timestamp.jsx +5 -2
- data/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_elapsed.html.erb +9 -0
- data/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_elapsed.jsx +10 -0
- data/app/pb_kits/playbook/pb_timestamp/timestamp.rb +4 -1
- data/app/pb_kits/playbook/pb_timestamp/timestamp.test.js +164 -0
- data/app/pb_kits/playbook/pb_tooltip/_tooltip.tsx +0 -4
- data/app/pb_kits/playbook/pb_tooltip/tooltip.test.jsx +11 -8
- data/app/pb_kits/playbook/tokens/_colors.scss +74 -74
- data/app/pb_kits/playbook/tokens/_typography.scss +8 -8
- data/app/pb_kits/playbook/utilities/_flexbox.scss +11 -11
- data/app/pb_kits/playbook/utilities/{_align_content.scss → flexbox_global_props/_align_content.scss} +0 -0
- data/app/pb_kits/playbook/utilities/{_align_items.scss → flexbox_global_props/_align_items.scss} +0 -0
- data/app/pb_kits/playbook/utilities/{_align_self.scss → flexbox_global_props/_align_self.scss} +0 -0
- data/app/pb_kits/playbook/utilities/{_flex.scss → flexbox_global_props/_flex.scss} +0 -0
- data/app/pb_kits/playbook/utilities/{_flex_direction.scss → flexbox_global_props/_flex_direction.scss} +0 -0
- data/app/pb_kits/playbook/utilities/{_flex_grow.scss → flexbox_global_props/_flex_grow.scss} +0 -0
- data/app/pb_kits/playbook/utilities/{_flex_shrink.scss → flexbox_global_props/_flex_shrink.scss} +0 -0
- data/app/pb_kits/playbook/utilities/{_flex_wrap.scss → flexbox_global_props/_flex_wrap.scss} +0 -0
- data/app/pb_kits/playbook/utilities/{_justify_content.scss → flexbox_global_props/_justify_content.scss} +0 -0
- data/app/pb_kits/playbook/utilities/{_justify_self.scss → flexbox_global_props/_justify_self.scss} +0 -0
- data/app/pb_kits/playbook/utilities/{_order.scss → flexbox_global_props/_order.scss} +0 -0
- data/app/pb_kits/playbook/utilities/props.ts +1 -1
- data/app/pb_kits/playbook/utilities/test-utils.js +2 -3
- data/app/pb_kits/playbook/utilities/text.ts +1 -1
- data/lib/playbook/version.rb +2 -2
- metadata +56 -25
- data/app/pb_kits/playbook/pb_date_range_inline/_date_range_inline.jsx +0 -155
- data/app/pb_kits/playbook/pb_home_address_street/_home_address_street.jsx +0 -124
- data/app/pb_kits/playbook/pb_label_value/_label_value.jsx +0 -155
@@ -0,0 +1,77 @@
|
|
1
|
+
import React from 'react'
|
2
|
+
import { render, screen } from '../utilities/test-utils'
|
3
|
+
|
4
|
+
import IconValue from './_icon_value'
|
5
|
+
|
6
|
+
const testId = "iconvalue-kit";
|
7
|
+
|
8
|
+
describe("IconValue Kit", () => {
|
9
|
+
test("renders IconValue classname", () => {
|
10
|
+
render(
|
11
|
+
<IconValue
|
12
|
+
data={{ testid: testId }}
|
13
|
+
icon="clipboard"
|
14
|
+
text="33-123456"
|
15
|
+
/>
|
16
|
+
)
|
17
|
+
|
18
|
+
const kit = screen.getByTestId(testId)
|
19
|
+
expect(kit).toHaveClass("pb_icon_value_kit_left")
|
20
|
+
})
|
21
|
+
|
22
|
+
test("renders icon", () => {
|
23
|
+
render(
|
24
|
+
<IconValue
|
25
|
+
data={{ testid: testId }}
|
26
|
+
icon="clipboard"
|
27
|
+
text="33-123456"
|
28
|
+
/>
|
29
|
+
)
|
30
|
+
|
31
|
+
const kit = screen.getByTestId(testId)
|
32
|
+
const icon = kit.querySelector(".fa-clipboard.pb_icon_kit.fa-fw")
|
33
|
+
expect(icon).toBeInTheDocument()
|
34
|
+
})
|
35
|
+
|
36
|
+
test("renders value", () => {
|
37
|
+
render(
|
38
|
+
<IconValue
|
39
|
+
data={{ testid: testId }}
|
40
|
+
icon="clipboard"
|
41
|
+
text="33-123456"
|
42
|
+
/>
|
43
|
+
)
|
44
|
+
|
45
|
+
const kit = screen.getByTestId(testId)
|
46
|
+
const value = kit.querySelector(".pb_body_kit_light")
|
47
|
+
expect(value.textContent).toEqual("33-123456")
|
48
|
+
})
|
49
|
+
|
50
|
+
test("aligns content center", () => {
|
51
|
+
render(
|
52
|
+
<IconValue
|
53
|
+
align="center"
|
54
|
+
data={{ testid: testId }}
|
55
|
+
icon="clipboard"
|
56
|
+
text="33-123456"
|
57
|
+
/>
|
58
|
+
)
|
59
|
+
|
60
|
+
const kit = screen.getByTestId(testId)
|
61
|
+
expect(kit).toHaveClass("pb_icon_value_kit_center")
|
62
|
+
})
|
63
|
+
|
64
|
+
test("aligns content right", () => {
|
65
|
+
render(
|
66
|
+
<IconValue
|
67
|
+
align="right"
|
68
|
+
data={{ testid: testId }}
|
69
|
+
icon="clipboard"
|
70
|
+
text="33-123456"
|
71
|
+
/>
|
72
|
+
)
|
73
|
+
|
74
|
+
const kit = screen.getByTestId(testId)
|
75
|
+
expect(kit).toHaveClass("pb_icon_value_kit_right")
|
76
|
+
})
|
77
|
+
})
|
@@ -0,0 +1,123 @@
|
|
1
|
+
import React from "react";
|
2
|
+
import classnames from "classnames";
|
3
|
+
import DateTime from "../pb_kit/dateTime";
|
4
|
+
import { buildAriaProps, buildCss, buildDataProps } from "../utilities/props";
|
5
|
+
import { globalProps } from "../utilities/globalProps";
|
6
|
+
|
7
|
+
import Body from "../pb_body/_body";
|
8
|
+
import Caption from "../pb_caption/_caption";
|
9
|
+
import Flex from "../pb_flex/_flex";
|
10
|
+
import Icon from "../pb_icon/_icon";
|
11
|
+
import Title from "../pb_title/_title";
|
12
|
+
|
13
|
+
type LabelValueProps = {
|
14
|
+
active?: boolean;
|
15
|
+
aria?: { [key: string]: string };
|
16
|
+
className?: string;
|
17
|
+
dark?: boolean;
|
18
|
+
data?: object;
|
19
|
+
date?: Date;
|
20
|
+
id?: string;
|
21
|
+
label: string;
|
22
|
+
value?: string;
|
23
|
+
variant?: "default" | "details";
|
24
|
+
icon?: string;
|
25
|
+
description?: string;
|
26
|
+
title?: string;
|
27
|
+
};
|
28
|
+
|
29
|
+
const dateString = (value: DateTime) => {
|
30
|
+
const month = value.toMonthNum();
|
31
|
+
const day = value.toDay();
|
32
|
+
|
33
|
+
return ` · ${month}/${day}`;
|
34
|
+
};
|
35
|
+
|
36
|
+
const LabelValue = (props: LabelValueProps) => {
|
37
|
+
const {
|
38
|
+
active = false,
|
39
|
+
aria = {},
|
40
|
+
className,
|
41
|
+
dark = false,
|
42
|
+
data = {},
|
43
|
+
date,
|
44
|
+
description,
|
45
|
+
icon,
|
46
|
+
id,
|
47
|
+
label,
|
48
|
+
title,
|
49
|
+
value,
|
50
|
+
variant = "default",
|
51
|
+
} = props;
|
52
|
+
|
53
|
+
const ariaProps = buildAriaProps(aria);
|
54
|
+
const dataProps = buildDataProps(data);
|
55
|
+
const formattedDate = new DateTime({ value: date });
|
56
|
+
const variantClass = variant === "details" ? "details" : "";
|
57
|
+
const classes = classnames(
|
58
|
+
buildCss("pb_label_value_kit", variantClass),
|
59
|
+
globalProps(props),
|
60
|
+
className
|
61
|
+
);
|
62
|
+
|
63
|
+
return (
|
64
|
+
<div
|
65
|
+
{...ariaProps}
|
66
|
+
{...dataProps}
|
67
|
+
className={classes}
|
68
|
+
id={id}
|
69
|
+
title={title}
|
70
|
+
>
|
71
|
+
<Caption dark={dark} text={label} />
|
72
|
+
{variant === "details" ? (
|
73
|
+
<Flex inline vertical="center">
|
74
|
+
{icon && (
|
75
|
+
<Body color="light" dark={dark} marginRight="xs">
|
76
|
+
<Icon dark={dark} fixedWidth icon={icon} />
|
77
|
+
</Body>
|
78
|
+
)}
|
79
|
+
{description && (
|
80
|
+
<Body
|
81
|
+
color="light"
|
82
|
+
dark={dark}
|
83
|
+
marginRight="xs"
|
84
|
+
text={description}
|
85
|
+
/>
|
86
|
+
)}
|
87
|
+
{active === true ? (
|
88
|
+
<Flex inline vertical="center">
|
89
|
+
{title && (
|
90
|
+
<Title dark={dark} size={4} text={title} variant="link" />
|
91
|
+
)}
|
92
|
+
{date && (
|
93
|
+
<Title
|
94
|
+
dark={dark}
|
95
|
+
marginLeft="xs"
|
96
|
+
size={4}
|
97
|
+
text={" " + dateString(formattedDate)}
|
98
|
+
variant="link"
|
99
|
+
/>
|
100
|
+
)}
|
101
|
+
</Flex>
|
102
|
+
) : (
|
103
|
+
<>
|
104
|
+
{title && <Title dark={dark} size={4} text={title} />}
|
105
|
+
{date && (
|
106
|
+
<Title
|
107
|
+
dark={dark}
|
108
|
+
marginLeft="xs"
|
109
|
+
size={4}
|
110
|
+
text={" " + dateString(formattedDate)}
|
111
|
+
/>
|
112
|
+
)}
|
113
|
+
</>
|
114
|
+
)}
|
115
|
+
</Flex>
|
116
|
+
) : (
|
117
|
+
<Body dark={dark} text={value} />
|
118
|
+
)}
|
119
|
+
</div>
|
120
|
+
);
|
121
|
+
};
|
122
|
+
|
123
|
+
export default LabelValue;
|
@@ -0,0 +1,109 @@
|
|
1
|
+
import React from 'react'
|
2
|
+
import { render, screen } from '../utilities/test-utils'
|
3
|
+
|
4
|
+
import LabelValue from './_label_value'
|
5
|
+
|
6
|
+
const testId = "labelvalue-kit";
|
7
|
+
jest.useFakeTimers()
|
8
|
+
|
9
|
+
describe("LabelValue Kit", () => {
|
10
|
+
test("renders LabelValue classname", () => {
|
11
|
+
render(
|
12
|
+
<LabelValue
|
13
|
+
data={{ testid: testId }}
|
14
|
+
label="Role"
|
15
|
+
value="Administrator, Moderator"
|
16
|
+
/>
|
17
|
+
)
|
18
|
+
const kit = screen.getByTestId(testId)
|
19
|
+
expect(kit).toHaveClass("pb_label_value_kit")
|
20
|
+
})
|
21
|
+
|
22
|
+
test("renders label correctly", () => {
|
23
|
+
render(
|
24
|
+
<LabelValue
|
25
|
+
data={{ testid: testId }}
|
26
|
+
label="Role"
|
27
|
+
value="Administrator, Moderator"
|
28
|
+
/>
|
29
|
+
)
|
30
|
+
const kit = screen.getByTestId(testId)
|
31
|
+
const text = kit.querySelector(".pb_caption_kit_md")
|
32
|
+
expect(text.textContent).toEqual("Role")
|
33
|
+
})
|
34
|
+
|
35
|
+
test("renders value correctly", () => {
|
36
|
+
render(
|
37
|
+
<LabelValue
|
38
|
+
data={{ testid: testId }}
|
39
|
+
label="Role"
|
40
|
+
value="Administrator, Moderator"
|
41
|
+
/>
|
42
|
+
)
|
43
|
+
const kit = screen.getByTestId(testId)
|
44
|
+
const text = kit.querySelector(".pb_body_kit")
|
45
|
+
expect(text.textContent).toEqual("Administrator, Moderator")
|
46
|
+
})
|
47
|
+
|
48
|
+
test("renders icon if included with details variant", () => {
|
49
|
+
render(
|
50
|
+
<LabelValue
|
51
|
+
data={{ testid: testId }}
|
52
|
+
icon="truck"
|
53
|
+
label="Installer"
|
54
|
+
title="JD Installations LLC"
|
55
|
+
variant="details"
|
56
|
+
/>
|
57
|
+
)
|
58
|
+
const kit = screen.getByTestId(testId)
|
59
|
+
const icon = kit.querySelector(".fa-truck.pb_icon_kit.fa-fw")
|
60
|
+
expect(icon).toBeInTheDocument()
|
61
|
+
})
|
62
|
+
|
63
|
+
test("renders title if included with details variant", () => {
|
64
|
+
render(
|
65
|
+
<LabelValue
|
66
|
+
data={{ testid: testId }}
|
67
|
+
icon="truck"
|
68
|
+
label="Installer"
|
69
|
+
title="JD Installations LLC"
|
70
|
+
variant="details"
|
71
|
+
/>
|
72
|
+
)
|
73
|
+
const kit = screen.getByTestId(testId)
|
74
|
+
const text = kit.querySelector(".pb_title_kit_size_4")
|
75
|
+
expect(text.textContent).toEqual("JD Installations LLC")
|
76
|
+
})
|
77
|
+
|
78
|
+
test("renders date if included with details variant", () => {
|
79
|
+
render(
|
80
|
+
<LabelValue
|
81
|
+
data={{ testid: testId }}
|
82
|
+
date={new Date('18 Nov 2019')}
|
83
|
+
description="33-12345"
|
84
|
+
icon="home"
|
85
|
+
label="Project"
|
86
|
+
title="Jefferson-Smith"
|
87
|
+
variant="details"
|
88
|
+
/>
|
89
|
+
)
|
90
|
+
const text = screen.getByText("11/18", {exact: false})
|
91
|
+
expect(text).toBeInTheDocument()
|
92
|
+
})
|
93
|
+
|
94
|
+
test("renders title if included with details variant", () => {
|
95
|
+
render(
|
96
|
+
<LabelValue
|
97
|
+
active
|
98
|
+
data={{ testid: testId }}
|
99
|
+
icon="truck"
|
100
|
+
label="Installer"
|
101
|
+
title="JD Installations LLC"
|
102
|
+
variant="details"
|
103
|
+
/>
|
104
|
+
)
|
105
|
+
const kit = screen.getByTestId(testId)
|
106
|
+
const activeProp = kit.querySelector(".pb_title_kit_size_4_link")
|
107
|
+
expect(activeProp).toBeInTheDocument()
|
108
|
+
})
|
109
|
+
})
|
@@ -1,5 +1,3 @@
|
|
1
|
-
/* @flow */
|
2
|
-
|
3
1
|
import React from 'react'
|
4
2
|
import classnames from 'classnames'
|
5
3
|
import { buildAriaProps, buildCss, buildDataProps } from '../utilities/props'
|
@@ -7,8 +5,8 @@ import { buildAriaProps, buildCss, buildDataProps } from '../utilities/props'
|
|
7
5
|
import { globalProps } from '../utilities/globalProps'
|
8
6
|
|
9
7
|
type LayoutPropTypes = {
|
10
|
-
aria?:
|
11
|
-
children?:
|
8
|
+
aria?: {[key: string]: string},
|
9
|
+
children?: React.ReactChild[] | React.ReactChild,
|
12
10
|
className?: string,
|
13
11
|
collapse?: "xs" | "sm" | "md" | "lg" | "xl",
|
14
12
|
dark?: boolean,
|
@@ -23,28 +21,28 @@ type LayoutPropTypes = {
|
|
23
21
|
}
|
24
22
|
|
25
23
|
type LayoutSideProps = {
|
26
|
-
children:
|
24
|
+
children: React.ReactNode[] | React.ReactNode,
|
27
25
|
className?: string,
|
28
26
|
}
|
29
27
|
|
30
28
|
type LayoutBodyProps = {
|
31
|
-
children:
|
29
|
+
children: React.ReactNode[] | React.ReactNode,
|
32
30
|
className?: string,
|
33
31
|
}
|
34
32
|
|
35
33
|
type LayoutItemProps = {
|
36
|
-
children:
|
34
|
+
children: React.ReactNode[] | React.ReactNode,
|
37
35
|
className?: string,
|
38
36
|
size?: "sm" | "md" | "lg"
|
39
37
|
}
|
40
38
|
|
41
39
|
type LayoutHeaderProps = {
|
42
|
-
children:
|
40
|
+
children: React.ReactNode[] | React.ReactNode,
|
43
41
|
className?: string,
|
44
42
|
}
|
45
43
|
|
46
44
|
type LayoutFooterProps = {
|
47
|
-
children:
|
45
|
+
children: React.ReactNode[] | React.ReactNode,
|
48
46
|
className?: string,
|
49
47
|
}
|
50
48
|
|
@@ -99,8 +97,6 @@ const Footer = (props: LayoutFooterProps) => {
|
|
99
97
|
)
|
100
98
|
}
|
101
99
|
|
102
|
-
// Main componenet
|
103
|
-
|
104
100
|
const Layout = (props: LayoutPropTypes) => {
|
105
101
|
const {
|
106
102
|
aria = {},
|
@@ -138,25 +134,23 @@ const Layout = (props: LayoutPropTypes) => {
|
|
138
134
|
? ''
|
139
135
|
: buildCss('layout', position, 'collapse', collapse)
|
140
136
|
|
141
|
-
const layoutChildren =
|
142
|
-
typeof children === 'object' && children.length ? children : [children]
|
137
|
+
const layoutChildren = React.Children.toArray(children)
|
143
138
|
|
144
|
-
const subComponentTags = (tagName) => {
|
139
|
+
const subComponentTags = (tagName: string) => {
|
145
140
|
return layoutChildren
|
146
|
-
.filter((c) => {
|
147
|
-
return c.type
|
141
|
+
.filter((c: React.ReactElement & {type: {displayName: string}}) => {
|
142
|
+
return c.type?.displayName === tagName
|
148
143
|
})
|
149
144
|
.map((child, i) => {
|
150
|
-
return React.cloneElement(child, {
|
145
|
+
return React.cloneElement(child as React.ReactElement, {
|
151
146
|
key: `${tagName.toLowerCase()}-${i}`,
|
152
147
|
})
|
153
148
|
})
|
154
149
|
}
|
155
150
|
|
156
151
|
const nonSideChildren = layoutChildren.filter(
|
157
|
-
(child
|
152
|
+
(child: React.ReactElement & {type: {displayName: string}}) => child.type?.displayName !== 'Side'
|
158
153
|
)
|
159
|
-
|
160
154
|
return (
|
161
155
|
<div
|
162
156
|
{...ariaProps}
|
@@ -0,0 +1,97 @@
|
|
1
|
+
import React from "react"
|
2
|
+
import { render, cleanup } from "../utilities/test-utils"
|
3
|
+
import { Layout, Card } from ".."
|
4
|
+
|
5
|
+
function LayoutTest(props) {
|
6
|
+
return (
|
7
|
+
<Layout {...props}>
|
8
|
+
<Layout.Side>{"Light"}</Layout.Side>
|
9
|
+
<Layout.Body>{"Body"}</Layout.Body>
|
10
|
+
</Layout>
|
11
|
+
)
|
12
|
+
}
|
13
|
+
|
14
|
+
test("render all color variants", () => {
|
15
|
+
const testValues = [undefined, "light", "dark", "gradient"]
|
16
|
+
testValues.forEach((variant) => {
|
17
|
+
const { getByTestId } = render(
|
18
|
+
<LayoutTest data={{ testid: `test-${variant}` }}
|
19
|
+
variant={variant} />
|
20
|
+
)
|
21
|
+
expect(getByTestId(`test-${variant}`)).toHaveClass(
|
22
|
+
`pb_layout_kit_sidebar_size_md_left_${
|
23
|
+
variant == undefined ? "light" : variant
|
24
|
+
}`
|
25
|
+
)
|
26
|
+
|
27
|
+
cleanup()
|
28
|
+
})
|
29
|
+
})
|
30
|
+
|
31
|
+
test("render transparent class", () => {
|
32
|
+
const id = "transparent"
|
33
|
+
|
34
|
+
const { getByTestId } = render(
|
35
|
+
<LayoutTest data={{ testid: `test-${id}` }}
|
36
|
+
variant={id} />
|
37
|
+
)
|
38
|
+
expect(getByTestId(`test-${id}`)).toHaveClass(
|
39
|
+
`pb_layout_kit_sidebar_size_md_left_${id}`
|
40
|
+
)
|
41
|
+
|
42
|
+
cleanup()
|
43
|
+
})
|
44
|
+
|
45
|
+
test("render all sizes variants", () => {
|
46
|
+
const testValues = ["xs", "sm", "md", "lg", "xl"]
|
47
|
+
testValues.forEach((size) => {
|
48
|
+
const { getByTestId } = render(
|
49
|
+
<LayoutTest data={{ testid: `test-${size}` }}
|
50
|
+
size={size} />
|
51
|
+
)
|
52
|
+
expect(getByTestId(`test-${size}`)).toHaveClass(
|
53
|
+
`pb_layout_kit_sidebar_size_${size}_left_light`
|
54
|
+
)
|
55
|
+
|
56
|
+
cleanup()
|
57
|
+
})
|
58
|
+
})
|
59
|
+
|
60
|
+
test("render all layout variants", () => {
|
61
|
+
const testValues = [
|
62
|
+
{
|
63
|
+
layout: "collection",
|
64
|
+
expected: "pb_layout_kit_collection",
|
65
|
+
},
|
66
|
+
{
|
67
|
+
layout: "collection_detail",
|
68
|
+
expected: "pb_layout_kit_collection_detail_size_md_left_light",
|
69
|
+
},
|
70
|
+
{
|
71
|
+
layout: "content",
|
72
|
+
expected: "pb_layout_kit_content_size_md_left_light",
|
73
|
+
},
|
74
|
+
{
|
75
|
+
layout: "kanban",
|
76
|
+
expected: "pb_layout_kit_kanban",
|
77
|
+
},
|
78
|
+
{
|
79
|
+
layout: "masonry",
|
80
|
+
expected: "pb_layout_kit_masonry_size_md_left_light",
|
81
|
+
},
|
82
|
+
]
|
83
|
+
|
84
|
+
testValues.forEach(({ layout, expected }) => {
|
85
|
+
const { getByTestId } = render(
|
86
|
+
<Layout data={{ testid: `test-${layout}` }}
|
87
|
+
layout={layout}>
|
88
|
+
<Layout.Body>
|
89
|
+
<Card>{"Card content"}</Card>
|
90
|
+
</Layout.Body>
|
91
|
+
</Layout>
|
92
|
+
)
|
93
|
+
|
94
|
+
expect(getByTestId(`test-${layout}`)).toHaveClass(expected)
|
95
|
+
cleanup()
|
96
|
+
})
|
97
|
+
})
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import React from 'react'
|
2
|
-
import { fireEvent, render, screen
|
2
|
+
import { cleanup, fireEvent, render, screen } from '../utilities/test-utils'
|
3
3
|
|
4
4
|
import { Lightbox } from '../'
|
5
5
|
|
@@ -27,6 +27,7 @@ test('Kit renders', () => {
|
|
27
27
|
const kit = screen.getByTestId(testId)
|
28
28
|
expect(kit).toHaveClass(`${kitClass} customClass`)
|
29
29
|
expect(kit).toBeInTheDocument()
|
30
|
+
cleanup()
|
30
31
|
})
|
31
32
|
|
32
33
|
test('Shows selected images', () => {
|
@@ -67,9 +68,12 @@ test('Shows selected images', () => {
|
|
67
68
|
)
|
68
69
|
|
69
70
|
expect(image).toHaveAttribute('src', TEST_PHOTOS[0])
|
71
|
+
cleanup()
|
70
72
|
})
|
71
73
|
|
72
74
|
test('Closes on escape key', async () => {
|
75
|
+
const mockClose = jest.fn()
|
76
|
+
|
73
77
|
render(
|
74
78
|
<Lightbox
|
75
79
|
data={{ testid: testId }}
|
@@ -77,25 +81,29 @@ test('Closes on escape key', async () => {
|
|
77
81
|
iconSize="3x"
|
78
82
|
id="test1"
|
79
83
|
initialPhoto={0}
|
80
|
-
onClose={
|
84
|
+
onClose={mockClose}
|
81
85
|
photos={TEST_PHOTOS}
|
82
86
|
/>
|
83
87
|
)
|
84
88
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
89
|
+
fireEvent.keyDown(
|
90
|
+
global.window,
|
91
|
+
{
|
92
|
+
bubbles: true,
|
93
|
+
key: "Escape",
|
94
|
+
code: "Escape",
|
95
|
+
keyCode: 27,
|
96
|
+
charCode: 27
|
97
|
+
}
|
92
98
|
)
|
93
99
|
|
94
|
-
|
95
|
-
|
100
|
+
expect(mockClose).toHaveBeenCalled()
|
101
|
+
cleanup()
|
96
102
|
})
|
97
103
|
|
98
|
-
test('Closes on close button', () => {
|
104
|
+
test('Closes on close button', async () => {
|
105
|
+
const mockClose = jest.fn()
|
106
|
+
|
99
107
|
render(
|
100
108
|
<Lightbox
|
101
109
|
data={{ testid: testId }}
|
@@ -103,7 +111,7 @@ test('Closes on close button', () => {
|
|
103
111
|
iconSize="3x"
|
104
112
|
id="test1"
|
105
113
|
initialPhoto={0}
|
106
|
-
onClose={
|
114
|
+
onClose={mockClose}
|
107
115
|
photos={TEST_PHOTOS}
|
108
116
|
/>
|
109
117
|
)
|
@@ -119,6 +127,6 @@ test('Closes on close button', () => {
|
|
119
127
|
}),
|
120
128
|
)
|
121
129
|
|
122
|
-
|
123
|
-
|
130
|
+
expect(mockClose).toHaveBeenCalled()
|
131
|
+
cleanup()
|
124
132
|
})
|
@@ -4,7 +4,7 @@ module Playbook
|
|
4
4
|
module PbPopover
|
5
5
|
class Popover < Playbook::KitBase
|
6
6
|
prop :position, type: Playbook::Props::Enum,
|
7
|
-
values: %w[top bottom left right],
|
7
|
+
values: %w[top bottom left right top-start top-end bottom-start bottom-end right-start right-end left-start left-end],
|
8
8
|
default: "left"
|
9
9
|
prop :trigger_element_id
|
10
10
|
prop :tooltip_id
|
@@ -3,7 +3,7 @@ import classnames from "classnames";
|
|
3
3
|
|
4
4
|
import DateTime from "../pb_kit/dateTime";
|
5
5
|
import { buildCss } from "../utilities/props";
|
6
|
-
import { globalProps } from "../utilities/globalProps";
|
6
|
+
import { globalProps, GlobalProps } from "../utilities/globalProps";
|
7
7
|
|
8
8
|
import Body from "../pb_body/_body";
|
9
9
|
import Caption from "../pb_caption/_caption";
|
@@ -20,7 +20,7 @@ type TimeProps = {
|
|
20
20
|
size?: "md" | "sm";
|
21
21
|
showTimezone?: boolean;
|
22
22
|
timeZone?: string;
|
23
|
-
}
|
23
|
+
} & GlobalProps
|
24
24
|
|
25
25
|
const Time = (props: TimeProps) => {
|
26
26
|
const {
|
@@ -21,6 +21,7 @@ type TimestampProps = {
|
|
21
21
|
id?: string,
|
22
22
|
showDate?: boolean,
|
23
23
|
showUser?: boolean,
|
24
|
+
hideUpdated?: boolean,
|
24
25
|
showTimezone?: boolean,
|
25
26
|
variant?: "default" | "elapsed" | "updated"
|
26
27
|
}
|
@@ -37,6 +38,7 @@ const Timestamp = (props: TimestampProps) => {
|
|
37
38
|
timezone,
|
38
39
|
showDate = true,
|
39
40
|
showUser = false,
|
41
|
+
hideUpdated = false,
|
40
42
|
showTimezone = false,
|
41
43
|
variant = 'default',
|
42
44
|
} = props
|
@@ -57,6 +59,7 @@ const Timestamp = (props: TimestampProps) => {
|
|
57
59
|
const dateDisplay = `${dateTimestamp.toMonth()} ${dateTimestamp.toDay()}`
|
58
60
|
const shouldShowUser = showUser == true && text.length > 0
|
59
61
|
const shouldShowTimezone = showTimezone == true && timezone.length > 0
|
62
|
+
const updatedText = hideUpdated ? "" : "Last updated"
|
60
63
|
const userDisplay = shouldShowUser ? ` by ${text}` : ''
|
61
64
|
|
62
65
|
let timeDisplay = `${dateTimestamp.toHour()}:${dateTimestamp.toMinute()}${dateTimestamp.toMeridian()}`
|
@@ -81,7 +84,7 @@ const Timestamp = (props: TimestampProps) => {
|
|
81
84
|
}
|
82
85
|
|
83
86
|
const formatElapsedString = () => {
|
84
|
-
return
|
87
|
+
return `${updatedText} ${userDisplay} ${dateTimestamp.value.fromNow()}`
|
85
88
|
}
|
86
89
|
|
87
90
|
const captionText = () => {
|
@@ -89,7 +92,7 @@ const Timestamp = (props: TimestampProps) => {
|
|
89
92
|
case 'updated':
|
90
93
|
return formatUpdatedString(userDisplay, dateTimestamp)
|
91
94
|
case 'elapsed':
|
92
|
-
return formatElapsedString(userDisplay, timeDisplay)
|
95
|
+
return formatElapsedString(userDisplay, timeDisplay, updatedText)
|
93
96
|
default:
|
94
97
|
return showDate ? timestamp ? fullDateDisplay() : text : fullTimeDisplay()
|
95
98
|
}
|