playbook_ui 12.17.1 → 12.18.0.pre.alpha.PLAY603datepickerquickpickinputpresetdropdown617
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/pb_kits/playbook/index.js +1 -1
- data/app/pb_kits/playbook/pb_avatar_action_button/avatar_action_button.html.erb +1 -2
- data/app/pb_kits/playbook/pb_collapsible/_collapsible.tsx +2 -2
- data/app/pb_kits/playbook/pb_date_picker/_date_picker.scss +26 -0
- data/app/pb_kits/playbook/pb_date_picker/_date_picker.tsx +99 -95
- 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 +1 -1
- data/app/pb_kits/playbook/pb_date_picker/date_picker.test.js +44 -1
- data/app/pb_kits/playbook/pb_date_picker/date_picker_helper.ts +34 -2
- data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_quick_pick.html.erb +8 -0
- data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_quick_pick.jsx +18 -0
- data/app/pb_kits/playbook/pb_date_picker/docs/example.yml +2 -0
- data/app/pb_kits/playbook/pb_date_picker/docs/index.js +2 -1
- data/app/pb_kits/playbook/pb_date_picker/plugins/quickPick.tsx +161 -0
- data/app/pb_kits/playbook/pb_date_picker/sass_partials/_calendar_input_icon.scss +4 -3
- data/app/pb_kits/playbook/pb_date_picker/sass_partials/_quick_pick_styles.scss +75 -0
- data/app/pb_kits/playbook/pb_docs/kit_api.html.erb +48 -36
- data/app/pb_kits/playbook/pb_docs/kit_api.rb +97 -9
- data/app/pb_kits/playbook/pb_docs/kit_example.html.erb +1 -1
- data/app/pb_kits/playbook/pb_docs/kit_example.rb +9 -5
- data/app/pb_kits/playbook/pb_lightbox/_lightbox.tsx +8 -0
- data/app/pb_kits/playbook/pb_lightbox/docs/_lightbox_current_photo.jsx +121 -0
- data/app/pb_kits/playbook/pb_lightbox/docs/_lightbox_current_photo.md +1 -0
- data/app/pb_kits/playbook/pb_lightbox/docs/example.yml +1 -0
- data/app/pb_kits/playbook/pb_lightbox/docs/index.js +1 -0
- data/app/pb_kits/playbook/pb_nav/_item.tsx +7 -7
- data/app/pb_kits/playbook/pb_nav/_nav.tsx +4 -4
- data/app/pb_kits/playbook/pb_nav/_subtle_mixin.scss +1 -1
- data/app/pb_kits/playbook/pb_rich_text_editor/TipTap/EditorButton.tsx +49 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/TipTap/EditorTypes.ts +9 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/TipTap/Toolbar.tsx +62 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/TipTap/ToolbarDropdown.tsx +139 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/TipTap/ToolbarHistory.tsx +45 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/TipTap/ToolbarNodes.tsx +59 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/_rich_text_editor.scss +1 -1
- data/app/pb_kits/playbook/pb_rich_text_editor/_rich_text_editor.tsx +28 -12
- data/app/pb_kits/playbook/pb_rich_text_editor/_tiptap_styles.scss +231 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_description.md +1 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_default.jsx +36 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_default.md +4 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/example.yml +1 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/index.js +1 -0
- data/app/pb_kits/playbook/pb_time_range_inline/_time_range_inline.tsx +185 -0
- data/app/pb_kits/playbook/pb_time_range_inline/time_range_inline.test.js +85 -0
- data/app/pb_kits/playbook/pb_title/_title.tsx +1 -1
- data/app/pb_kits/playbook/pb_title_detail/_title_detail.tsx +45 -0
- data/app/pb_kits/playbook/pb_title_detail/title_detail.test.js +71 -0
- data/app/pb_kits/playbook/pb_toggle/{_toggle.jsx → _toggle.tsx} +20 -22
- data/app/pb_kits/playbook/pb_toggle/toggle.test.js +67 -0
- data/app/pb_kits/playbook/pb_tooltip/_tooltip.scss +11 -6
- data/app/pb_kits/playbook/pb_tooltip/docs/_tooltip_default.html.erb +4 -4
- data/app/pb_kits/playbook/pb_tooltip/docs/_tooltip_with_icon_circle.html.erb +1 -2
- data/app/pb_kits/playbook/pb_tooltip/docs/example.yml +0 -1
- data/app/pb_kits/playbook/pb_user/_user.tsx +1 -1
- data/lib/playbook/markdown/helper.rb +50 -71
- data/lib/playbook/markdown.rb +0 -1
- data/lib/playbook/number_spacing.rb +10 -10
- data/lib/playbook/position.rb +10 -10
- data/lib/playbook/spacing.rb +10 -10
- data/lib/playbook/version.rb +2 -2
- data/lib/playbook/z_index.rb +10 -10
- metadata +31 -14
- data/app/pb_kits/playbook/pb_time_range_inline/_time_range_inline.jsx +0 -172
- data/app/pb_kits/playbook/pb_title_detail/_title_detail.jsx +0 -44
- data/app/pb_kits/playbook/pb_tooltip/docs/_tooltip_white.html.erb +0 -9
- data/lib/playbook/markdown/template_handler.rb +0 -47
@@ -0,0 +1,231 @@
|
|
1
|
+
@import "../tokens/border_radius";
|
2
|
+
@import "../tokens/colors";
|
3
|
+
@import "../tokens/spacing";
|
4
|
+
@import "../tokens/titles";
|
5
|
+
@import "../tokens/line_height";
|
6
|
+
@import "../tokens/typography";
|
7
|
+
@import "../tokens/shadows";
|
8
|
+
@import "../tokens/transition";
|
9
|
+
|
10
|
+
[class^="pb_rich_text_editor_kit"] {
|
11
|
+
.toolbar_button {
|
12
|
+
display: flex;
|
13
|
+
align-items: center;
|
14
|
+
background: $transparent;
|
15
|
+
border: none;
|
16
|
+
border-radius: $border_rad_heaviest;
|
17
|
+
color: $text_lt_light;
|
18
|
+
cursor: pointer;
|
19
|
+
&_icon {
|
20
|
+
width: $space_xl + 2;
|
21
|
+
height: $space_xl + 2;
|
22
|
+
}
|
23
|
+
&.open {
|
24
|
+
color: $primary;
|
25
|
+
}
|
26
|
+
&.is-active,
|
27
|
+
&:active {
|
28
|
+
color: $primary;
|
29
|
+
background-color: $bg_light;
|
30
|
+
}
|
31
|
+
&:hover:not([disabled]) {
|
32
|
+
background-color: $neutral_subtle;
|
33
|
+
}
|
34
|
+
&:disabled {
|
35
|
+
.pb_icon_kit {
|
36
|
+
color: $border_light;
|
37
|
+
}
|
38
|
+
}
|
39
|
+
&:focus-visible {
|
40
|
+
outline: none !important;
|
41
|
+
}
|
42
|
+
}
|
43
|
+
|
44
|
+
.toolbar {
|
45
|
+
border-radius: $border_rad_heaviest $border_rad_heaviest 0 0;
|
46
|
+
border: 1px solid $border_light;
|
47
|
+
overflow-x: auto;
|
48
|
+
&_block {
|
49
|
+
gap: $space_xs;
|
50
|
+
}
|
51
|
+
.editor-dropdown-button {
|
52
|
+
background: transparent;
|
53
|
+
border: none;
|
54
|
+
color: $text_lt_light;
|
55
|
+
cursor: pointer;
|
56
|
+
font-weight: $light;
|
57
|
+
padding: ($space_xs - 1) 0px;
|
58
|
+
width: $space_xl * 3;
|
59
|
+
&:focus-visible {
|
60
|
+
box-shadow: unset;
|
61
|
+
}
|
62
|
+
}
|
63
|
+
}
|
64
|
+
|
65
|
+
.ProseMirror {
|
66
|
+
background: $white;
|
67
|
+
border: 1px solid $border_light;
|
68
|
+
border-top-color: transparent;
|
69
|
+
border-bottom-right-radius: $border_rad_heaviest;
|
70
|
+
border-bottom-left-radius: $border_rad_heaviest;
|
71
|
+
height: 100%;
|
72
|
+
padding: 1rem 1.5rem 1.5rem 1.5rem;
|
73
|
+
line-height: $lh_loose;
|
74
|
+
@include transition_default;
|
75
|
+
:first-child {
|
76
|
+
margin-top: 0;
|
77
|
+
}
|
78
|
+
|
79
|
+
h4,
|
80
|
+
h5,
|
81
|
+
h6,
|
82
|
+
ul,
|
83
|
+
ol,
|
84
|
+
blockquote,
|
85
|
+
p {
|
86
|
+
margin: 1rem 0 0 0;
|
87
|
+
}
|
88
|
+
|
89
|
+
code {
|
90
|
+
font-family: monospace;
|
91
|
+
background: $bg_light;
|
92
|
+
padding: 0.1rem 0.3rem;
|
93
|
+
margin: 0 5px;
|
94
|
+
box-shadow: 0 2px 10px $shadow;
|
95
|
+
border-radius: 0.25rem;
|
96
|
+
overflow: hidden;
|
97
|
+
font-size: ($text_small - 1px);
|
98
|
+
}
|
99
|
+
|
100
|
+
pre {
|
101
|
+
background: $bg_dark;
|
102
|
+
padding: $space_sm;
|
103
|
+
border-radius: $border_rad_heaviest;
|
104
|
+
margin: 1.5rem 0 2rem 0;
|
105
|
+
code {
|
106
|
+
background: transparent;
|
107
|
+
box-shadow: none;
|
108
|
+
border: 0;
|
109
|
+
color: #faf6e4;
|
110
|
+
}
|
111
|
+
}
|
112
|
+
a {
|
113
|
+
color: $primary;
|
114
|
+
border-bottom: 1px solid $primary;
|
115
|
+
&:hover {
|
116
|
+
color: $text_lt_default;
|
117
|
+
border-bottom: 1px solid $text_lt_default;
|
118
|
+
}
|
119
|
+
}
|
120
|
+
blockquote {
|
121
|
+
font-size: $font_larger;
|
122
|
+
padding: $space_sm $space_md;
|
123
|
+
font-style: italic;
|
124
|
+
p {
|
125
|
+
margin: 0;
|
126
|
+
}
|
127
|
+
}
|
128
|
+
&:focus-visible {
|
129
|
+
outline: unset;
|
130
|
+
border-top-color: $primary;
|
131
|
+
@include transition_default;
|
132
|
+
}
|
133
|
+
h1 {
|
134
|
+
font-size: $text_largest;
|
135
|
+
line-height: $text_larger;
|
136
|
+
font-weight: $bolder;
|
137
|
+
letter-spacing: $lspace_tight;
|
138
|
+
margin: 2.1rem 0 0 0;
|
139
|
+
}
|
140
|
+
h2 {
|
141
|
+
font-size: $text_larger;
|
142
|
+
line-height: $text_larger;
|
143
|
+
font-weight: $bolder;
|
144
|
+
letter-spacing: $lspace_tight;
|
145
|
+
margin: 1.9rem 0 0 0;
|
146
|
+
}
|
147
|
+
h3 {
|
148
|
+
font-size: $text_large;
|
149
|
+
line-height: $text_large;
|
150
|
+
font-weight: $bolder;
|
151
|
+
letter-spacing: $lspace_tight;
|
152
|
+
margin: 1.7rem 0 0 0;
|
153
|
+
}
|
154
|
+
h4,
|
155
|
+
h5,
|
156
|
+
h6 {
|
157
|
+
font-size: $text_base;
|
158
|
+
line-height: $text_base;
|
159
|
+
letter-spacing: $lspace_tight;
|
160
|
+
font-weight: $bolder;
|
161
|
+
}
|
162
|
+
hr {
|
163
|
+
margin: 2.2rem 0;
|
164
|
+
box-sizing: content-box;
|
165
|
+
overflow: hidden;
|
166
|
+
background: transparent;
|
167
|
+
border-bottom: 1px solid $transparent;
|
168
|
+
height: 1px;
|
169
|
+
padding: 0;
|
170
|
+
background-color: $border_light;
|
171
|
+
border: 0;
|
172
|
+
}
|
173
|
+
ol {
|
174
|
+
margin: 1rem 0 0 0;
|
175
|
+
padding-left: $space_md;
|
176
|
+
list-style: decimal;
|
177
|
+
li {
|
178
|
+
margin: 2px 0;
|
179
|
+
p {
|
180
|
+
margin: 0;
|
181
|
+
}
|
182
|
+
}
|
183
|
+
}
|
184
|
+
ul {
|
185
|
+
list-style-position: disc;
|
186
|
+
margin: 1rem 0 0 0;
|
187
|
+
padding-left: $space_md;
|
188
|
+
li {
|
189
|
+
margin: 2px 0;
|
190
|
+
p {
|
191
|
+
margin: 0;
|
192
|
+
}
|
193
|
+
}
|
194
|
+
}
|
195
|
+
}
|
196
|
+
}
|
197
|
+
|
198
|
+
.pb_tiptap_toolbar_dropdown_list_item {
|
199
|
+
&.is-active,
|
200
|
+
&:active {
|
201
|
+
color: $primary;
|
202
|
+
background-color: $bg_light;
|
203
|
+
border-radius: unset !important;
|
204
|
+
.pb_nav_list_item_text,
|
205
|
+
.pb_nav_list_item_icon_left {
|
206
|
+
color: $primary !important;
|
207
|
+
}
|
208
|
+
}
|
209
|
+
&:hover {
|
210
|
+
background-color: $neutral_subtle;
|
211
|
+
border-radius: unset !important;
|
212
|
+
.pb_nav_list_item_text,
|
213
|
+
.pb_nav_list_item_icon_left {
|
214
|
+
background-color: unset;
|
215
|
+
color: $text_lt_light !important;
|
216
|
+
}
|
217
|
+
.pb_nav_list_item_link {
|
218
|
+
background-color: unset !important;
|
219
|
+
}
|
220
|
+
}
|
221
|
+
}
|
222
|
+
.pb_rich_text_editor_advanced_container {
|
223
|
+
transition: box-shadow 0.3s ease-in-out, border-radius 0.3s ease-in-out;
|
224
|
+
&:focus-visible,
|
225
|
+
&:focus-within {
|
226
|
+
outline: unset;
|
227
|
+
box-shadow: 0 0 0 1px $primary;
|
228
|
+
border-radius: $border_rad_heaviest;
|
229
|
+
transition: box-shadow 0.3s ease-in-out, border-radius 0.3s ease-in-out;
|
230
|
+
}
|
231
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
NOTE: All editors have a default max-width of "md". Use our [Max Width global prop](https://playbook.powerapp.cloud/visual_guidelines/max_width) to override this default, as necessary.
|
@@ -0,0 +1,36 @@
|
|
1
|
+
import React from 'react'
|
2
|
+
import { RichTextEditor } from '../..'
|
3
|
+
import { useEditor, EditorContent } from "@tiptap/react"
|
4
|
+
import StarterKit from "@tiptap/starter-kit"
|
5
|
+
import Link from '@tiptap/extension-link'
|
6
|
+
|
7
|
+
|
8
|
+
const RichTextEditorAdvancedDefault = (props) => {
|
9
|
+
|
10
|
+
const editor = useEditor({
|
11
|
+
extensions: [
|
12
|
+
StarterKit,
|
13
|
+
Link
|
14
|
+
],
|
15
|
+
content:"Add your text here. You can format your text, add links, quotes, and bullets."
|
16
|
+
})
|
17
|
+
if (!editor) {
|
18
|
+
return null
|
19
|
+
}
|
20
|
+
|
21
|
+
|
22
|
+
|
23
|
+
|
24
|
+
return (
|
25
|
+
<div>
|
26
|
+
<RichTextEditor
|
27
|
+
advancedEditor={editor}
|
28
|
+
{...props}
|
29
|
+
>
|
30
|
+
<EditorContent editor={editor}/>
|
31
|
+
</RichTextEditor>
|
32
|
+
</div>
|
33
|
+
)
|
34
|
+
}
|
35
|
+
|
36
|
+
export default RichTextEditorAdvancedDefault
|
@@ -0,0 +1,4 @@
|
|
1
|
+
The advanced variant leverages Tiptap to unlock additional UI options (e.g., consolidated nav toolbar, styling, etc.) as well as several extensions (see [Tiptap docs](https://tiptap.dev/extensions) for more). To leverage this variant, Tiptap __must be installed__ in your project. Complete docs for using the library can be found [here](https://tiptap.dev/). To get started with this variant, see the Code Example below for required imports as well as the basic setup.
|
2
|
+
|
3
|
+
|
4
|
+
NOTE: Once the Tiptap editor is initialized as shown below, you must pass that instance to the kit via the `advancedEditor` prop.
|
@@ -7,3 +7,4 @@ export { default as RichTextEditorTemplates } from './_rich_text_editor_template
|
|
7
7
|
export { default as RichTextEditorToolbarBottom } from './_rich_text_editor_toolbar_bottom.jsx'
|
8
8
|
export { default as RichTextEditorInline } from './_rich_text_editor_inline.jsx'
|
9
9
|
export { default as RichTextEditorPreview } from './_rich_text_editor_preview.jsx'
|
10
|
+
export { default as RichTextEditorAdvancedDefault } from './_rich_text_editor_advanced_default.jsx'
|
@@ -0,0 +1,185 @@
|
|
1
|
+
import React from 'react'
|
2
|
+
import classnames from 'classnames'
|
3
|
+
|
4
|
+
import DateTime from '../pb_kit/dateTime'
|
5
|
+
import { globalProps, GlobalProps } from '../utilities/globalProps'
|
6
|
+
import { buildAriaProps, buildDataProps } from '../utilities/props'
|
7
|
+
|
8
|
+
import Body from '../pb_body/_body'
|
9
|
+
import Caption from '../pb_caption/_caption'
|
10
|
+
import Icon from '../pb_icon/_icon'
|
11
|
+
|
12
|
+
type TimeRangeInlineProps = {
|
13
|
+
aria?: { [key: string]: string },
|
14
|
+
className?: string,
|
15
|
+
id?: string,
|
16
|
+
data?: { [key: string]: string },
|
17
|
+
alignment?: "left" | "center" | "vertical",
|
18
|
+
size?: "sm" | "xs",
|
19
|
+
dark?: boolean,
|
20
|
+
icon?: boolean,
|
21
|
+
timezone?: boolean,
|
22
|
+
startTime: string,
|
23
|
+
endTime: string,
|
24
|
+
} & GlobalProps
|
25
|
+
|
26
|
+
const timezoneString = (dateValue: string) => {
|
27
|
+
const date = new DateTime({ value: dateValue })
|
28
|
+
return `${date.convertToTimezone()}`
|
29
|
+
}
|
30
|
+
|
31
|
+
const dateTimestamp = (dateValue: string) => {
|
32
|
+
const date = new DateTime({ value: dateValue })
|
33
|
+
return `${date.toHour()}:${date.toMinute()}${date.toMeridian()}`
|
34
|
+
}
|
35
|
+
|
36
|
+
const dateTimeIso = (dateValue: string) => {
|
37
|
+
const date = new DateTime({ value: dateValue })
|
38
|
+
return date.toIso()
|
39
|
+
}
|
40
|
+
|
41
|
+
const TimeRangeInline = (props: TimeRangeInlineProps) => {
|
42
|
+
const {
|
43
|
+
aria = {},
|
44
|
+
className,
|
45
|
+
data = {},
|
46
|
+
alignment = 'left',
|
47
|
+
size = 'sm',
|
48
|
+
dark = false,
|
49
|
+
icon = false,
|
50
|
+
timezone = false,
|
51
|
+
startTime,
|
52
|
+
endTime,
|
53
|
+
id,
|
54
|
+
} = props
|
55
|
+
|
56
|
+
const dataProps: { [key: string]: string } = buildDataProps(data)
|
57
|
+
const ariaProps: { [key: string]: string } = buildAriaProps(aria)
|
58
|
+
|
59
|
+
const separator = (
|
60
|
+
<Body color="light">
|
61
|
+
<Icon
|
62
|
+
className="pb_time_range_inline_arrow"
|
63
|
+
dark={dark}
|
64
|
+
fixedWidth
|
65
|
+
icon="long-arrow-right"
|
66
|
+
/>
|
67
|
+
</Body>
|
68
|
+
)
|
69
|
+
|
70
|
+
const iconContent = () => {
|
71
|
+
return (
|
72
|
+
icon &&
|
73
|
+
<Body
|
74
|
+
color="light"
|
75
|
+
tag="span"
|
76
|
+
>
|
77
|
+
<Icon
|
78
|
+
className="pb_time_range_inline_icon"
|
79
|
+
dark={dark}
|
80
|
+
fixedWidth
|
81
|
+
icon="clock"
|
82
|
+
size={size}
|
83
|
+
tag="span"
|
84
|
+
/>
|
85
|
+
</Body>
|
86
|
+
)
|
87
|
+
}
|
88
|
+
|
89
|
+
return (
|
90
|
+
<div
|
91
|
+
{...ariaProps}
|
92
|
+
{...dataProps}
|
93
|
+
className={classnames('pb_time_range_inline_kit_' + alignment, globalProps(props), className)}
|
94
|
+
id={id}
|
95
|
+
>
|
96
|
+
<div className="pb_time_range_inline_wrapper">
|
97
|
+
{size == 'xs' &&
|
98
|
+
<>
|
99
|
+
<Caption
|
100
|
+
dark={dark}
|
101
|
+
tag="span"
|
102
|
+
>
|
103
|
+
{iconContent()}
|
104
|
+
<time dateTime={dateTimeIso(startTime)}>
|
105
|
+
{` ${dateTimestamp(
|
106
|
+
startTime
|
107
|
+
)} `}
|
108
|
+
</time>
|
109
|
+
</Caption>
|
110
|
+
<Caption
|
111
|
+
className="pb_time_range_inline_arrow"
|
112
|
+
dark={dark}
|
113
|
+
tag="span"
|
114
|
+
>
|
115
|
+
{separator}
|
116
|
+
</Caption>
|
117
|
+
<Caption
|
118
|
+
dark={dark}
|
119
|
+
tag="span"
|
120
|
+
>
|
121
|
+
<time dateTime={dateTimeIso(endTime)}>
|
122
|
+
{` ${dateTimestamp(
|
123
|
+
endTime
|
124
|
+
)} `}
|
125
|
+
</time>
|
126
|
+
</Caption>
|
127
|
+
{timezone &&
|
128
|
+
<Caption
|
129
|
+
className="pb_time_range_inline_timezone"
|
130
|
+
dark={dark}
|
131
|
+
tag="span"
|
132
|
+
>
|
133
|
+
{timezoneString(endTime)}
|
134
|
+
</Caption>
|
135
|
+
}
|
136
|
+
</>
|
137
|
+
}
|
138
|
+
{size == 'sm' &&
|
139
|
+
<>
|
140
|
+
<Body
|
141
|
+
dark={dark}
|
142
|
+
tag="span"
|
143
|
+
>
|
144
|
+
{iconContent()}
|
145
|
+
<time dateTime={dateTimeIso(startTime)}>
|
146
|
+
{` ${dateTimestamp(
|
147
|
+
startTime
|
148
|
+
)} `}
|
149
|
+
</time>
|
150
|
+
</Body>
|
151
|
+
<Body
|
152
|
+
className="pb_time_range_inline_arrow"
|
153
|
+
dark={dark}
|
154
|
+
tag="span"
|
155
|
+
>
|
156
|
+
{separator}
|
157
|
+
</Body>
|
158
|
+
<Body
|
159
|
+
dark={dark}
|
160
|
+
tag="span"
|
161
|
+
>
|
162
|
+
<time dateTime={dateTimeIso(endTime)}>
|
163
|
+
{` ${dateTimestamp(
|
164
|
+
endTime
|
165
|
+
)} `}
|
166
|
+
</time>
|
167
|
+
</Body>
|
168
|
+
{timezone &&
|
169
|
+
<Body
|
170
|
+
className="pb_time_range_inline_timezone"
|
171
|
+
color="light"
|
172
|
+
dark={dark}
|
173
|
+
tag="span"
|
174
|
+
>
|
175
|
+
{timezoneString(endTime)}
|
176
|
+
</Body>
|
177
|
+
}
|
178
|
+
</>
|
179
|
+
}
|
180
|
+
</div>
|
181
|
+
</div>
|
182
|
+
)
|
183
|
+
}
|
184
|
+
|
185
|
+
export default TimeRangeInline
|
@@ -0,0 +1,85 @@
|
|
1
|
+
import React from 'react'
|
2
|
+
import { render, screen } from '../utilities/test-utils'
|
3
|
+
|
4
|
+
import TimeRangeInline from './_time_range_inline'
|
5
|
+
|
6
|
+
const testId = 'timeRangeInline'
|
7
|
+
const className = 'custom-class-name'
|
8
|
+
|
9
|
+
const TimeRangeInlineDefault = (props) => (
|
10
|
+
<>
|
11
|
+
<TimeRangeInline
|
12
|
+
aria={{ label: testId }}
|
13
|
+
className={className}
|
14
|
+
data={{ testid: testId }}
|
15
|
+
endTime="2012-08-02T17:49:29Z"
|
16
|
+
icon="true"
|
17
|
+
id={testId}
|
18
|
+
size="sm"
|
19
|
+
startTime="2012-08-02T15:49:29Z"
|
20
|
+
timezone="true"
|
21
|
+
{...props}
|
22
|
+
/>
|
23
|
+
</>
|
24
|
+
)
|
25
|
+
|
26
|
+
test('should pass data prop', () => {
|
27
|
+
render(<TimeRangeInlineDefault />)
|
28
|
+
const kit = screen.getByTestId(testId)
|
29
|
+
expect(kit).toBeInTheDocument()
|
30
|
+
})
|
31
|
+
|
32
|
+
test('should pass className prop', () => {
|
33
|
+
render(<TimeRangeInlineDefault />)
|
34
|
+
const kit = screen.getByTestId(testId)
|
35
|
+
expect(kit).toHaveClass(className)
|
36
|
+
})
|
37
|
+
|
38
|
+
test('should pass aria prop', () => {
|
39
|
+
render(<TimeRangeInlineDefault />)
|
40
|
+
const kit = screen.getByTestId(testId)
|
41
|
+
expect(kit).toHaveAttribute('aria-label', testId)
|
42
|
+
})
|
43
|
+
|
44
|
+
test('should pass id prop', () => {
|
45
|
+
render(<TimeRangeInlineDefault />)
|
46
|
+
const kit = screen.getByTestId(testId)
|
47
|
+
expect(kit).toHaveProperty('id', testId)
|
48
|
+
})
|
49
|
+
|
50
|
+
test('should have left alignment by default', () => {
|
51
|
+
render(<TimeRangeInlineDefault />)
|
52
|
+
const kit = screen.getByTestId(testId)
|
53
|
+
expect(kit).toHaveClass('pb_time_range_inline_kit_left')
|
54
|
+
})
|
55
|
+
|
56
|
+
test('should pass alignment prop', () => {
|
57
|
+
render(<TimeRangeInlineDefault alignment="right" />)
|
58
|
+
const kit = screen.getByTestId(testId)
|
59
|
+
expect(kit).toHaveClass('pb_time_range_inline_kit_right')
|
60
|
+
})
|
61
|
+
|
62
|
+
test('should have icon', () => {
|
63
|
+
render(<TimeRangeInlineDefault />)
|
64
|
+
const kit = screen.getByTestId(testId)
|
65
|
+
const icon = kit.querySelector('.pb_time_range_inline_icon')
|
66
|
+
expect(icon).toBeInTheDocument()
|
67
|
+
})
|
68
|
+
|
69
|
+
test('should have timezone', () => {
|
70
|
+
render(<TimeRangeInlineDefault />)
|
71
|
+
const kit = screen.getByTestId(testId)
|
72
|
+
expect(kit.querySelector('.pb_time_range_inline_timezone')).toBeInTheDocument()
|
73
|
+
})
|
74
|
+
|
75
|
+
test('should render startTime', () => {
|
76
|
+
render(<TimeRangeInlineDefault />)
|
77
|
+
const kit = screen.getByTestId(testId)
|
78
|
+
expect(kit).toHaveTextContent('11:49a')
|
79
|
+
})
|
80
|
+
|
81
|
+
test('should render endTime', () => {
|
82
|
+
render(<TimeRangeInlineDefault />)
|
83
|
+
const kit = screen.getByTestId(testId)
|
84
|
+
expect(kit).toHaveTextContent('1:49p')
|
85
|
+
})
|
@@ -39,7 +39,7 @@ const Title = (props: TitleProps): React.ReactElement => {
|
|
39
39
|
const classes = classnames(
|
40
40
|
buildCss('pb_title_kit', `size_${size}`, variant, color, getBold),
|
41
41
|
globalProps(props),
|
42
|
-
className
|
42
|
+
className
|
43
43
|
)
|
44
44
|
const Tag: React.ReactElement | any = `${tag}`
|
45
45
|
|
@@ -0,0 +1,45 @@
|
|
1
|
+
import React from 'react'
|
2
|
+
import classnames from 'classnames'
|
3
|
+
|
4
|
+
import { GlobalProps, globalProps } from '../utilities/globalProps'
|
5
|
+
import { buildAriaProps, buildCss, buildDataProps } from '../utilities/props'
|
6
|
+
|
7
|
+
import Body from '../pb_body/_body'
|
8
|
+
import Title from '../pb_title/_title'
|
9
|
+
|
10
|
+
type TitleDetailProps = {
|
11
|
+
align?: "left" | "center" | "right",
|
12
|
+
aria?: { [key: string]: string },
|
13
|
+
className?: string,
|
14
|
+
data?: { [key: string]: string },
|
15
|
+
detail: string,
|
16
|
+
id?: string,
|
17
|
+
title: string,
|
18
|
+
} & GlobalProps
|
19
|
+
|
20
|
+
const TitleDetail = (props: TitleDetailProps) => {
|
21
|
+
const { align = 'left', aria = {}, className, data = {}, detail, id, title } = props
|
22
|
+
const ariaProps = buildAriaProps(aria)
|
23
|
+
const dataProps = buildDataProps(data)
|
24
|
+
const pbCss = buildCss('pb_title_detail_kit', align)
|
25
|
+
|
26
|
+
return (
|
27
|
+
<div
|
28
|
+
{...ariaProps}
|
29
|
+
{...dataProps}
|
30
|
+
className={classnames(pbCss, globalProps(props), className)}
|
31
|
+
id={id}
|
32
|
+
>
|
33
|
+
<Title
|
34
|
+
size={4}
|
35
|
+
text={title}
|
36
|
+
/>
|
37
|
+
<Body
|
38
|
+
color="light"
|
39
|
+
text={detail}
|
40
|
+
/>
|
41
|
+
</div>
|
42
|
+
)
|
43
|
+
}
|
44
|
+
|
45
|
+
export default TitleDetail
|
@@ -0,0 +1,71 @@
|
|
1
|
+
import React from 'react'
|
2
|
+
import { render, screen } from '../utilities/test-utils'
|
3
|
+
|
4
|
+
import TitleDetail from './_title_detail'
|
5
|
+
|
6
|
+
const testId = 'titleDetail'
|
7
|
+
const className = 'custom-class-name'
|
8
|
+
const detail = 'Commits data and history'
|
9
|
+
const title = 'Email Notifications'
|
10
|
+
|
11
|
+
const TitleDetailDefault = (props) => (
|
12
|
+
<>
|
13
|
+
<TitleDetail
|
14
|
+
aria={{ label: testId }}
|
15
|
+
className={className}
|
16
|
+
data={{ testid: testId }}
|
17
|
+
detail={detail}
|
18
|
+
id={testId}
|
19
|
+
title={title}
|
20
|
+
{...props}
|
21
|
+
/>
|
22
|
+
</>
|
23
|
+
)
|
24
|
+
|
25
|
+
test('should pass data prop', () => {
|
26
|
+
render(<TitleDetailDefault />)
|
27
|
+
const kit = screen.getByTestId(testId)
|
28
|
+
expect(kit).toBeInTheDocument()
|
29
|
+
})
|
30
|
+
|
31
|
+
test('should pass className prop', () => {
|
32
|
+
render(<TitleDetailDefault />)
|
33
|
+
const kit = screen.getByTestId(testId)
|
34
|
+
expect(kit).toHaveClass(className)
|
35
|
+
})
|
36
|
+
|
37
|
+
test('should pass aria prop', () => {
|
38
|
+
render(<TitleDetailDefault />)
|
39
|
+
const kit = screen.getByTestId(testId)
|
40
|
+
expect(kit).toHaveAttribute('aria-label', testId)
|
41
|
+
})
|
42
|
+
|
43
|
+
test('should pass id prop', () => {
|
44
|
+
render(<TitleDetailDefault />)
|
45
|
+
const kit = screen.getByTestId(testId)
|
46
|
+
expect(kit).toHaveProperty('id', testId)
|
47
|
+
})
|
48
|
+
|
49
|
+
test('should have left align by default', () => {
|
50
|
+
render(<TitleDetailDefault />)
|
51
|
+
const kit = screen.getByTestId(testId)
|
52
|
+
expect(kit).toHaveClass('pb_title_detail_kit_left')
|
53
|
+
})
|
54
|
+
|
55
|
+
test('should pass align prop', () => {
|
56
|
+
render(<TitleDetailDefault align="right" />)
|
57
|
+
const kit = screen.getByTestId(testId)
|
58
|
+
expect(kit).toHaveClass('pb_title_detail_kit_right')
|
59
|
+
})
|
60
|
+
|
61
|
+
test('should render detail', () => {
|
62
|
+
render(<TitleDetailDefault />)
|
63
|
+
const kit = screen.getByTestId(testId)
|
64
|
+
expect(kit).toHaveTextContent(detail)
|
65
|
+
})
|
66
|
+
|
67
|
+
test('should render title', () => {
|
68
|
+
render(<TitleDetailDefault />)
|
69
|
+
const kit = screen.getByTestId(testId)
|
70
|
+
expect(kit).toHaveTextContent(title)
|
71
|
+
})
|