playbook_ui 14.0.0 → 14.1.0.pre.alpha.PA1477timestampkit3536
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_advanced_table/Components/TableHeaderCell.tsx +5 -2
- data/app/pb_kits/playbook/pb_advanced_table/SubKits/TableBody.tsx +24 -20
- data/app/pb_kits/playbook/pb_advanced_table/SubKits/TableHeader.tsx +17 -12
- data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.scss +86 -1
- data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.tsx +5 -1
- data/app/pb_kits/playbook/pb_advanced_table/advanced_table.test.jsx +30 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_responsive.jsx +67 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_responsive.md +1 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/example.yml +1 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/index.js +2 -1
- data/app/pb_kits/playbook/pb_avatar/_avatar.scss +0 -30
- data/app/pb_kits/playbook/pb_avatar/_avatar.tsx +19 -1
- data/app/pb_kits/playbook/pb_avatar/avatar.rb +44 -1
- data/app/pb_kits/playbook/pb_avatar/avatar.test.js +17 -0
- data/app/pb_kits/playbook/pb_date_picker/docs/_description.md +3 -1
- data/app/pb_kits/playbook/pb_fixed_confirmation_toast/_fixed_confirmation_toast.scss +1 -1
- data/app/pb_kits/playbook/pb_form/docs/_form_form_with.html.erb +1 -0
- data/app/pb_kits/playbook/pb_icon/_icon.tsx +3 -0
- data/app/pb_kits/playbook/pb_icon/icon.rb +2 -0
- data/app/pb_kits/playbook/pb_icon_circle/_icon_circle.tsx +2 -1
- data/app/pb_kits/playbook/pb_icon_circle/icon_circle.rb +2 -2
- data/app/pb_kits/playbook/pb_icon_stat_value/_icon_stat_value.scss +0 -11
- data/app/pb_kits/playbook/pb_icon_stat_value/_icon_stat_value.tsx +3 -2
- data/app/pb_kits/playbook/pb_icon_stat_value/docs/_icon_stat_value_color.html.erb +1 -0
- data/app/pb_kits/playbook/pb_icon_stat_value/icon_stat_value.rb +2 -2
- data/app/pb_kits/playbook/pb_icon_stat_value/icon_stat_value.test.js +5 -4
- data/app/pb_kits/playbook/pb_nav/_horizontal_nav.scss +1 -1
- data/app/pb_kits/playbook/pb_online_status/_online_status.scss +52 -5
- data/app/pb_kits/playbook/pb_online_status/_online_status.tsx +6 -1
- data/app/pb_kits/playbook/pb_online_status/docs/_online_status_no_border.html.erb +1 -0
- data/app/pb_kits/playbook/pb_online_status/docs/_online_status_no_border.jsx +14 -0
- data/app/pb_kits/playbook/pb_online_status/docs/_online_status_size.html.erb +3 -0
- data/app/pb_kits/playbook/pb_online_status/docs/_online_status_size.jsx +25 -0
- data/app/pb_kits/playbook/pb_online_status/docs/example.yml +6 -2
- data/app/pb_kits/playbook/pb_online_status/docs/index.js +2 -0
- data/app/pb_kits/playbook/pb_online_status/online_status.rb +11 -1
- data/app/pb_kits/playbook/pb_online_status/online_status.test.js +31 -0
- data/app/pb_kits/playbook/pb_overlay/docs/_overlay_toggle.html.erb +61 -0
- data/app/pb_kits/playbook/pb_overlay/docs/_overlay_toggle.jsx +70 -0
- data/app/pb_kits/playbook/pb_overlay/docs/_overlay_toggle.md +1 -0
- data/app/pb_kits/playbook/pb_overlay/docs/example.yml +4 -2
- data/app/pb_kits/playbook/pb_overlay/docs/index.js +1 -0
- data/app/pb_kits/playbook/pb_star_rating/_star_rating.scss +83 -6
- data/app/pb_kits/playbook/pb_star_rating/docs/example.yml +3 -1
- data/app/pb_kits/playbook/pb_star_rating/index.js +73 -4
- data/app/pb_kits/playbook/pb_star_rating/star_rating.html.erb +1 -1
- data/app/pb_kits/playbook/pb_star_rating/star_rating.rb +2 -2
- data/app/pb_kits/playbook/pb_star_rating/stars/utils.tsx +5 -1
- data/app/pb_kits/playbook/pb_star_rating/subcomponents/_star_rating_interactive.tsx +50 -21
- data/app/pb_kits/playbook/pb_table/_table.tsx +1 -1
- data/app/pb_kits/playbook/pb_table/index.ts +4 -4
- data/app/pb_kits/playbook/pb_table/subcomponents/_table_body.tsx +1 -1
- data/app/pb_kits/playbook/pb_table/subcomponents/_table_cell.tsx +1 -1
- data/app/pb_kits/playbook/pb_table/subcomponents/_table_head.tsx +1 -1
- data/app/pb_kits/playbook/pb_table/subcomponents/_table_header.tsx +1 -1
- data/app/pb_kits/playbook/pb_table/subcomponents/_table_row.tsx +1 -1
- data/app/pb_kits/playbook/pb_table/table.test.js +2 -0
- data/app/pb_kits/playbook/pb_text_input/_text_input.tsx +1 -1
- data/app/pb_kits/playbook/pb_text_input/docs/_text_input_default.jsx +1 -1
- data/app/pb_kits/playbook/pb_textarea/_textarea.tsx +45 -27
- data/app/pb_kits/playbook/pb_textarea/index.ts +3 -3
- data/app/pb_kits/playbook/pb_time/_time.tsx +3 -3
- data/app/pb_kits/playbook/pb_time_range_inline/_time_range_inline.tsx +1 -1
- data/app/pb_kits/playbook/pb_timeline/_item.tsx +1 -1
- data/app/pb_kits/playbook/pb_timeline/_timeline.tsx +1 -1
- data/app/pb_kits/playbook/pb_timestamp/timestamp.rb +37 -2
- data/app/pb_kits/playbook/pb_title_detail/_title_detail.tsx +10 -10
- data/app/pb_kits/playbook/pb_toggle/_toggle.tsx +1 -1
- data/app/pb_kits/playbook/pb_tooltip/_tooltip.tsx +2 -2
- data/app/pb_kits/playbook/pb_treemap_chart/_treemap_chart.tsx +1 -2
- data/app/pb_kits/playbook/pb_treemap_chart/treemapChart.test.js +2 -0
- data/app/pb_kits/playbook/pb_typeahead/_typeahead.tsx +2 -2
- data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_multi_kit.html.erb +1 -1
- data/app/pb_kits/playbook/pb_typeahead/typeahead.rb +1 -0
- data/app/pb_kits/playbook/pb_user/_user.tsx +1 -1
- data/app/pb_kits/playbook/pb_user_badge/_user_badge.tsx +6 -6
- data/app/pb_kits/playbook/pb_user_badge/badges/million-dollar.tsx +236 -235
- data/app/pb_kits/playbook/pb_user_badge/badges/veteran.tsx +1 -1
- data/app/pb_kits/playbook/pb_walkthrough/_walkthrough.tsx +68 -63
- data/app/pb_kits/playbook/pb_weekday_stacked/_weekday_stacked.tsx +1 -1
- data/app/pb_kits/playbook/utilities/_positioning.scss +26 -15
- data/dist/chunks/_typeahead-D-4y9pbv.js +22 -0
- data/dist/chunks/_weekday_stacked-Cax4nrUa.js +45 -0
- data/dist/chunks/lazysizes-DHz07jlL.js +1 -0
- data/dist/chunks/{lib-Bf_E03gc.js → lib-BE0Z3F7x.js} +1 -1
- data/dist/chunks/{pb_form_validation-D0dhqeN2.js → pb_form_validation-TzZQ0Flx.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/version.rb +2 -2
- metadata +20 -11
- data/app/pb_kits/playbook/pb_online_status/_online_status_mixins.scss +0 -32
- data/dist/chunks/_typeahead-COUJ88EA.js +0 -22
- data/dist/chunks/_weekday_stacked-BAkwel5p.js +0 -45
- data/dist/chunks/lazysizes-B7xYodB-.js +0 -1
@@ -14,6 +14,29 @@ export default class PbStarRating extends PbEnhancedElement {
|
|
14
14
|
this.updateStarColors(clickedStarId);
|
15
15
|
this.updateHiddenInputValue(clickedStarId);
|
16
16
|
});
|
17
|
+
|
18
|
+
document.querySelectorAll(STAR_RATING_SELECTOR).forEach(star => {
|
19
|
+
star.addEventListener("mouseenter", (event) => {
|
20
|
+
const hoveredStarId = event.currentTarget.id
|
21
|
+
this.updateStarHoverColors(hoveredStarId);
|
22
|
+
})
|
23
|
+
|
24
|
+
star.addEventListener("mouseleave", () => {
|
25
|
+
this.removeStarHoverColors();
|
26
|
+
})
|
27
|
+
|
28
|
+
star.addEventListener("keydown", (event) => {
|
29
|
+
if (event.key === 'Enter' || event.key === ' ') {
|
30
|
+
event.preventDefault();
|
31
|
+
this.handleStarClick(star.id);
|
32
|
+
}
|
33
|
+
})
|
34
|
+
})
|
35
|
+
}
|
36
|
+
|
37
|
+
handleStarClick(starId) {
|
38
|
+
this.updateStarColors(starId);
|
39
|
+
this.updateHiddenInputValue(starId);
|
17
40
|
}
|
18
41
|
|
19
42
|
updateStarColors(clickedStarId) {
|
@@ -27,16 +50,21 @@ export default class PbStarRating extends PbEnhancedElement {
|
|
27
50
|
if (starId <= clickedStarId) {
|
28
51
|
if (star.classList.contains("yellow_star")) {
|
29
52
|
icon.classList.add("yellow-star-selected");
|
30
|
-
} else if (star.classList.contains("
|
53
|
+
} else if (star.classList.contains("primary_star_light")) {
|
31
54
|
icon.classList.add("primary-star-selected");
|
32
|
-
} else if (star.classList.contains("
|
33
|
-
icon.classList.add("
|
55
|
+
} else if (star.classList.contains("primary_star_dark")) {
|
56
|
+
icon.classList.add("primary-star-selected");
|
57
|
+
} else if (star.classList.contains("subtle_star_light")) {
|
58
|
+
icon.classList.add("subtle-star-selected");
|
59
|
+
} else if (star.classList.contains("subtle_star_dark")) {
|
60
|
+
icon.classList.add("subtle-star-selected");
|
34
61
|
} else {
|
35
62
|
icon.classList.add("yellow-star-selected");
|
36
63
|
}
|
37
64
|
} else {
|
38
|
-
icon.classList.remove("yellow-star-selected", "primary-star-selected", "
|
65
|
+
icon.classList.remove("yellow-star-selected", "primary-star-selected", "subtle-star-selected");
|
39
66
|
}
|
67
|
+
icon.classList.remove("star-hovered");
|
40
68
|
}
|
41
69
|
});
|
42
70
|
}
|
@@ -47,4 +75,45 @@ export default class PbStarRating extends PbEnhancedElement {
|
|
47
75
|
hiddenInput.value = value;
|
48
76
|
}
|
49
77
|
}
|
78
|
+
|
79
|
+
updateStarHoverColors(hoveredStarId) {
|
80
|
+
const allStars = document.querySelectorAll(STAR_RATING_SELECTOR);
|
81
|
+
|
82
|
+
allStars.forEach(star => {
|
83
|
+
const starId = star.id;
|
84
|
+
const icon = star.querySelector(".interactive-star-icon");
|
85
|
+
|
86
|
+
if (icon) {
|
87
|
+
if (starId <= hoveredStarId) {
|
88
|
+
if (!icon.classList.contains("yellow-star-selected") &&
|
89
|
+
!icon.classList.contains("primary-star-selected") &&
|
90
|
+
!icon.classList.contains("subtle-star-selected")) {
|
91
|
+
icon.classList.add("star-hovered");
|
92
|
+
}
|
93
|
+
} else {
|
94
|
+
icon.classList.remove("star-hovered");
|
95
|
+
}
|
96
|
+
}
|
97
|
+
});
|
98
|
+
}
|
99
|
+
|
100
|
+
|
101
|
+
removeStarHoverColors() {
|
102
|
+
const allStars = document.querySelectorAll(STAR_RATING_SELECTOR);
|
103
|
+
|
104
|
+
allStars.forEach(star => {
|
105
|
+
const icon = star.querySelector(".interactive-star-icon");
|
106
|
+
if (icon) {
|
107
|
+
if (!icon.classList.contains("yellow-star-selected") &&
|
108
|
+
!icon.classList.contains("primary-star-selected") &&
|
109
|
+
!icon.classList.contains("subtle-star-selected")) {
|
110
|
+
icon.classList.remove("star-hovered");
|
111
|
+
}
|
112
|
+
}
|
113
|
+
});
|
114
|
+
}
|
115
|
+
|
116
|
+
isStarSelected() {
|
117
|
+
return document.querySelectorAll(".yellow-star-selected, .primary-star-selected, .subtle-star-selected").length > 0;
|
118
|
+
}
|
50
119
|
}
|
@@ -47,7 +47,7 @@
|
|
47
47
|
<%= pb_rails("flex", props: { orientation: "row" }) do %>
|
48
48
|
<% object.denominator.times do |index| %>
|
49
49
|
<div data-pb-star-rating id="<%= index + 1 %>" class="<%= star_color %>">
|
50
|
-
<%= pb_rails("icon", props: { classname: "#{background_star_color} pb_star_#{size} interactive-star-icon", custom_icon: Playbook::Engine.root.join(background_star_path)} ) %>
|
50
|
+
<%= pb_rails("icon", props: { classname: "#{background_star_color} pb_star_#{size} interactive-star-icon", custom_icon: Playbook::Engine.root.join(background_star_path), tabindex: 0 } ) %>
|
51
51
|
</div>
|
52
52
|
<% end %>
|
53
53
|
<% end %>
|
@@ -52,9 +52,9 @@ module Playbook
|
|
52
52
|
when "yellow"
|
53
53
|
"yellow_star"
|
54
54
|
when "primary"
|
55
|
-
"
|
55
|
+
dark ? "primary_star_dark" : "primary_star_light"
|
56
56
|
when "subtle"
|
57
|
-
dark ? "
|
57
|
+
dark ? "subtle_star_dark" : "subtle_star_light"
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
@@ -53,7 +53,11 @@ const starOutline = (
|
|
53
53
|
)
|
54
54
|
|
55
55
|
export const getStarIconObject = (backgroundType: string, color: string, dark: boolean, size: string) => {
|
56
|
-
const colorClassName = color === "subtle"
|
56
|
+
const colorClassName = color === "subtle"
|
57
|
+
? (dark ? "suble_star_dark" : "suble_star_light")
|
58
|
+
: color === "primary"
|
59
|
+
? (dark ? "primary_star_dark" : "primary_star_light")
|
60
|
+
: `${color}_star`
|
57
61
|
const backgroundClassName = backgroundType === "outline" ? (dark ? "outline_empty_star_dark" : "outline_empty_star_light") : (dark ? "empty_star_dark" : "empty_star_light")
|
58
62
|
|
59
63
|
return {
|
@@ -23,40 +23,69 @@ const StarRatingInteractive = (props: StarRatingInteractiveProps) => {
|
|
23
23
|
size,
|
24
24
|
} = props
|
25
25
|
const [interactiveStarValue, setInteractiveStarValue] = useState(0)
|
26
|
+
const [hoverStarValue, setHoverStarValue] = useState<number | null>(null)
|
26
27
|
const starIcon = getStarIconObject(backgroundType, colorOption, dark, size)
|
27
28
|
|
28
29
|
const handleOnClick = (interactiveStarValue: number) => {
|
29
30
|
setInteractiveStarValue(interactiveStarValue)
|
30
31
|
onClick && onClick(interactiveStarValue)
|
31
32
|
}
|
33
|
+
const handleMouseEnter = (value: number) => {
|
34
|
+
setHoverStarValue(value);
|
35
|
+
}
|
36
|
+
const handleMouseLeave = () => {
|
37
|
+
setHoverStarValue(null);
|
38
|
+
}
|
39
|
+
const handleOnKeyDown = (event: React.KeyboardEvent<HTMLDivElement>, starIndex: number) => {
|
40
|
+
if (event.key === 'Enter' || event.key === ' ') {
|
41
|
+
event.preventDefault()
|
42
|
+
handleOnClick(starIndex)
|
43
|
+
}
|
44
|
+
}
|
32
45
|
|
33
46
|
return (
|
34
47
|
<Flex className="star_flex_area">
|
35
|
-
{[...Array(denominator)].map((_, index) =>
|
36
|
-
|
37
|
-
|
48
|
+
{[...Array(denominator)].map((_, index) => {
|
49
|
+
const starIndex = index + 1
|
50
|
+
const isFilled = starIndex <= interactiveStarValue
|
51
|
+
const isHovered = hoverStarValue !== null && starIndex > interactiveStarValue && starIndex <= hoverStarValue
|
52
|
+
|
53
|
+
const baseClass = dark
|
54
|
+
? starIcon[backgroundType].className.replace("empty_star_light", "empty_star_dark")
|
55
|
+
: starIcon[backgroundType].className
|
56
|
+
|
57
|
+
let starClass = baseClass
|
58
|
+
if (isFilled) {
|
59
|
+
starClass = starClass.replace(/(empty_star_light|empty_star_dark)/, '')
|
60
|
+
starClass += ` ${starIcon[colorOption].className}`
|
61
|
+
}
|
62
|
+
if (isHovered) {
|
63
|
+
starClass += " star-hovered"
|
64
|
+
}
|
65
|
+
if (isFilled && starIndex === interactiveStarValue) {
|
66
|
+
starClass += " star-selected"
|
67
|
+
}
|
68
|
+
|
69
|
+
return (
|
70
|
+
<div
|
71
|
+
key={index}
|
72
|
+
onKeyDown={(event) => handleOnKeyDown(event, starIndex)}
|
73
|
+
>
|
38
74
|
<Icon
|
39
|
-
className={
|
75
|
+
className={starClass.trim()}
|
40
76
|
cursor="pointer"
|
41
|
-
customIcon={starIcon[
|
42
|
-
htmlOptions={{
|
77
|
+
customIcon={starIcon[backgroundType].icon as unknown as { [key: string]: SVGElement }}
|
78
|
+
htmlOptions={{
|
79
|
+
onClick: () => handleOnClick(starIndex),
|
80
|
+
onMouseEnter: () => handleMouseEnter(starIndex),
|
81
|
+
onMouseLeave: () => handleMouseLeave(),
|
82
|
+
}}
|
43
83
|
icon=""
|
84
|
+
tabIndex={0}
|
44
85
|
/>
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
<React.Fragment key={index}>
|
49
|
-
<Icon
|
50
|
-
className={starIcon[backgroundType].className}
|
51
|
-
cursor="pointer"
|
52
|
-
customIcon={starIcon[backgroundType].icon as unknown as { [key: string]: SVGElement }}
|
53
|
-
htmlOptions={{ onClick: () => handleOnClick(index + 1) }}
|
54
|
-
icon=""
|
55
|
-
/>
|
56
|
-
</React.Fragment>
|
57
|
-
)}
|
58
|
-
</React.Fragment>
|
59
|
-
))}
|
86
|
+
</div>
|
87
|
+
);
|
88
|
+
})}
|
60
89
|
</Flex>
|
61
90
|
)
|
62
91
|
}
|
@@ -1,19 +1,19 @@
|
|
1
1
|
import PbEnhancedElement from '../pb_enhanced_element'
|
2
2
|
|
3
3
|
export default class PbTable extends PbEnhancedElement {
|
4
|
-
static get selector() {
|
4
|
+
static get selector(): string {
|
5
5
|
return '.table-responsive-collapse'
|
6
6
|
}
|
7
7
|
|
8
|
-
connect() {
|
8
|
+
connect(): void {
|
9
9
|
const tables = document.querySelectorAll('.table-responsive-collapse');
|
10
10
|
|
11
11
|
// Each Table
|
12
12
|
[].forEach.call(tables, (table: HTMLTableElement) => {
|
13
13
|
// Header Titles
|
14
|
-
|
14
|
+
const headers: string[] = [];
|
15
15
|
[].forEach.call(table.querySelectorAll('th'), (header: HTMLTableCellElement) => {
|
16
|
-
|
16
|
+
const colSpan = header.colSpan
|
17
17
|
for (let i = 0; i < colSpan; i++) {
|
18
18
|
headers.push(header.textContent.replace(/\r?\n|\r/, ''));
|
19
19
|
}
|
@@ -5,12 +5,12 @@ import TextInput from '../../pb_text_input/_text_input'
|
|
5
5
|
import Title from '../../pb_title/_title'
|
6
6
|
|
7
7
|
const TextInputDefault = (props) => {
|
8
|
+
const [firstName, setFirstName] = useState('')
|
8
9
|
const handleOnChangeFirstName = ({ target }) => {
|
9
10
|
setFirstName(target.value)
|
10
11
|
}
|
11
12
|
const ref = React.createRef()
|
12
13
|
|
13
|
-
const [firstName, setFirstName] = useState('')
|
14
14
|
const [formFields, setFormFields] = useState({
|
15
15
|
firstName: 'Jane',
|
16
16
|
lastName: 'Doe',
|
@@ -52,14 +52,15 @@ const Textarea = ({
|
|
52
52
|
label,
|
53
53
|
maxCharacters,
|
54
54
|
name,
|
55
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
55
56
|
onChange = () => {},
|
56
57
|
placeholder,
|
57
58
|
required,
|
58
59
|
rows = 4,
|
59
60
|
value,
|
60
61
|
...props
|
61
|
-
}: TextareaProps
|
62
|
-
ref = useRef<HTMLTextAreaElement>(null)
|
62
|
+
}: TextareaProps) => {
|
63
|
+
const ref = useRef<HTMLTextAreaElement>(null)
|
63
64
|
useEffect(() => {
|
64
65
|
if (ref.current && resize === 'auto') {
|
65
66
|
PbTextarea.addMatch(ref.current)
|
@@ -71,58 +72,75 @@ const Textarea = ({
|
|
71
72
|
const resizeClass = `resize_${resize}`
|
72
73
|
const classes = classnames('pb_textarea_kit', errorClass, inlineClass, resizeClass, globalProps(props), className)
|
73
74
|
const noCount = typeof characterCount !== 'undefined'
|
74
|
-
const ariaProps: {[key: string]:
|
75
|
-
const dataProps: {[key: string]:
|
75
|
+
const ariaProps: {[key: string]: string} = buildAriaProps(aria)
|
76
|
+
const dataProps: {[key: string]: string} = buildDataProps(data)
|
76
77
|
const htmlProps = buildHtmlProps(htmlOptions)
|
77
|
-
const characterCounter = () => {
|
78
|
-
return maxCharacters && characterCount ? `${checkIfZero(characterCount)} / ${maxCharacters}` : `${checkIfZero(characterCount)}`
|
79
|
-
}
|
80
|
-
|
81
78
|
const checkIfZero = (characterCount: string | number) => {
|
82
79
|
return characterCount == 0 ? characterCount.toString() : characterCount
|
83
80
|
}
|
81
|
+
const characterCounter = () => {
|
82
|
+
return maxCharacters && characterCount ? `${checkIfZero(characterCount)} / ${maxCharacters}` : `${checkIfZero(characterCount)}`
|
83
|
+
}
|
84
84
|
|
85
85
|
return (
|
86
86
|
<div
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
87
|
+
{...ariaProps}
|
88
|
+
{...dataProps}
|
89
|
+
{...htmlProps}
|
90
|
+
className={classes}
|
91
91
|
>
|
92
92
|
<Caption text={label} />
|
93
93
|
{children || (
|
94
94
|
<textarea
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
95
|
+
className="pb_textarea_kit"
|
96
|
+
disabled={disabled}
|
97
|
+
name={name}
|
98
|
+
onChange={onChange}
|
99
|
+
placeholder={placeholder}
|
100
|
+
ref={ref}
|
101
|
+
required={required}
|
102
|
+
rows={rows}
|
103
|
+
value={value}
|
104
|
+
{...props}
|
105
105
|
/>
|
106
106
|
)}
|
107
107
|
|
108
108
|
{error ? (
|
109
109
|
<>
|
110
110
|
{characterCount ? (
|
111
|
-
<Flex
|
111
|
+
<Flex
|
112
|
+
spacing="between"
|
113
|
+
vertical="center"
|
114
|
+
>
|
112
115
|
<FlexItem>
|
113
|
-
<Body
|
116
|
+
<Body
|
117
|
+
margin="none"
|
118
|
+
status="negative"
|
119
|
+
text={error}
|
120
|
+
/>
|
114
121
|
</FlexItem>
|
115
122
|
<FlexItem>
|
116
|
-
<Caption
|
123
|
+
<Caption
|
124
|
+
margin="none"
|
125
|
+
size="xs"
|
126
|
+
text={characterCounter()}
|
127
|
+
/>
|
117
128
|
</FlexItem>
|
118
129
|
</Flex>
|
119
130
|
) : (
|
120
|
-
<Body
|
131
|
+
<Body
|
132
|
+
status="negative"
|
133
|
+
text={error}
|
134
|
+
/>
|
121
135
|
)}
|
122
136
|
</>
|
123
137
|
) : (
|
124
138
|
noCount && (
|
125
|
-
<Caption
|
139
|
+
<Caption
|
140
|
+
margin="none"
|
141
|
+
size="xs"
|
142
|
+
text={characterCounter()}
|
143
|
+
/>
|
126
144
|
)
|
127
145
|
)}
|
128
146
|
</div>
|
@@ -3,16 +3,16 @@ import PbEnhancedElement from '../pb_enhanced_element'
|
|
3
3
|
export default class PbTextarea extends PbEnhancedElement {
|
4
4
|
style: {[key: string]: string}
|
5
5
|
scrollHeight: string
|
6
|
-
static get selector() {
|
6
|
+
static get selector(): string {
|
7
7
|
return '.resize_auto textarea'
|
8
8
|
}
|
9
9
|
|
10
|
-
onInput() {
|
10
|
+
onInput(): void {
|
11
11
|
this.style.height = 'auto'
|
12
12
|
this.style.height = (this.scrollHeight) + 'px'
|
13
13
|
}
|
14
14
|
|
15
|
-
connect() {
|
15
|
+
connect(): void {
|
16
16
|
this.element.setAttribute('style', 'height:' + (this.element.scrollHeight) + 'px;overflow-y:hidden;')
|
17
17
|
this.element.addEventListener('input', this.onInput, false)
|
18
18
|
}
|
@@ -24,7 +24,7 @@ type TimeProps = {
|
|
24
24
|
unstyled?: boolean;
|
25
25
|
} & GlobalProps
|
26
26
|
|
27
|
-
const Time = (props: TimeProps) => {
|
27
|
+
const Time = (props: TimeProps): React.ReactElement => {
|
28
28
|
const {
|
29
29
|
align,
|
30
30
|
className,
|
@@ -47,8 +47,8 @@ const Time = (props: TimeProps) => {
|
|
47
47
|
|
48
48
|
return (
|
49
49
|
<div
|
50
|
-
|
51
|
-
|
50
|
+
{...htmlProps}
|
51
|
+
className={classes}
|
52
52
|
>
|
53
53
|
{showIcon && (
|
54
54
|
unstyled
|
@@ -36,7 +36,7 @@ const dateTimeIso = (dateValue: Date) => {
|
|
36
36
|
return DateTime.toIso(dateValue)
|
37
37
|
}
|
38
38
|
|
39
|
-
const TimeRangeInline = (props: TimeRangeInlineProps) => {
|
39
|
+
const TimeRangeInline = (props: TimeRangeInlineProps): React.ReactElement => {
|
40
40
|
const {
|
41
41
|
aria = {},
|
42
42
|
className,
|
@@ -26,7 +26,7 @@ const TimelineItem = ({
|
|
26
26
|
iconColor = 'default',
|
27
27
|
lineStyle = 'solid',
|
28
28
|
...props
|
29
|
-
}: ItemProps) => {
|
29
|
+
}: ItemProps): React.ReactElement => {
|
30
30
|
const timelineItemCss = buildCss('pb_timeline_item_kit', lineStyle)
|
31
31
|
|
32
32
|
const htmlProps = buildHtmlProps(htmlOptions)
|
@@ -27,7 +27,7 @@ const Timeline = ({
|
|
27
27
|
orientation = 'horizontal',
|
28
28
|
showDate = false,
|
29
29
|
...props
|
30
|
-
}: TimelineProps) => {
|
30
|
+
}: TimelineProps): React.ReactElement => {
|
31
31
|
const ariaProps = buildAriaProps(aria)
|
32
32
|
const dataProps = buildDataProps(data)
|
33
33
|
const htmlProps = buildHtmlProps(htmlOptions)
|
@@ -27,6 +27,15 @@ module Playbook
|
|
27
27
|
values: %w[default elapsed updated],
|
28
28
|
default: "default"
|
29
29
|
|
30
|
+
# Variables to use with pb_time_ago method
|
31
|
+
SECS_PER_MIN = 60
|
32
|
+
SECS_PER_HOUR = 60 * SECS_PER_MIN
|
33
|
+
SECS_PER_DAY = 24 * SECS_PER_HOUR
|
34
|
+
SECS_PER_WEEK = 7 * SECS_PER_DAY
|
35
|
+
SECS_PER_MONTH = 4 * SECS_PER_WEEK
|
36
|
+
SECS_PER_YEAR = 12 * SECS_PER_MONTH
|
37
|
+
SECS_PER_CENT = 100 * SECS_PER_YEAR
|
38
|
+
|
30
39
|
def classname
|
31
40
|
generate_classname("pb_timestamp_kit", variant_class, align)
|
32
41
|
end
|
@@ -73,12 +82,38 @@ module Playbook
|
|
73
82
|
|
74
83
|
def format_elapsed_string
|
75
84
|
user_string = show_user ? " by #{text}" : ""
|
76
|
-
datetime_string = " #{
|
85
|
+
datetime_string = " #{pb_time_ago(pb_date_time.convert_to_timestamp)} ago"
|
86
|
+
datetime_string[1] = hide_updated ? datetime_string[1].upcase : datetime_string[1]
|
77
87
|
updated_string = hide_updated ? "" : "Last updated"
|
78
|
-
|
79
88
|
"#{updated_string}#{user_string}#{datetime_string}"
|
80
89
|
end
|
81
90
|
|
91
|
+
def pb_time_ago(value)
|
92
|
+
time_ago = DateTime.now.to_i - value.to_i
|
93
|
+
case time_ago
|
94
|
+
when (0...SECS_PER_MIN)
|
95
|
+
"a few seconds"
|
96
|
+
when (SECS_PER_MIN...SECS_PER_HOUR)
|
97
|
+
time = time_ago / SECS_PER_MIN
|
98
|
+
time == 1 ? "a minute" : "#{time_ago / SECS_PER_MIN} minutes"
|
99
|
+
when (SECS_PER_HOUR...SECS_PER_DAY)
|
100
|
+
time = time_ago / SECS_PER_HOUR
|
101
|
+
time == 1 ? "an hour" : "#{time_ago / SECS_PER_HOUR} hours"
|
102
|
+
when (SECS_PER_DAY...SECS_PER_WEEK)
|
103
|
+
time = time_ago / SECS_PER_DAY
|
104
|
+
time == 1 ? "a day" : "#{time_ago / SECS_PER_DAY} days"
|
105
|
+
when (SECS_PER_WEEK...SECS_PER_MONTH)
|
106
|
+
time = time_ago / SECS_PER_WEEK
|
107
|
+
time == 1 ? "a week" : "#{time_ago / SECS_PER_WEEK} weeks"
|
108
|
+
when (SECS_PER_MONTH...SECS_PER_YEAR)
|
109
|
+
time = time_ago / SECS_PER_MONTH
|
110
|
+
time == 1 ? "a month" : "#{time_ago / SECS_PER_MONTH} months"
|
111
|
+
when (SECS_PER_YEAR...SECS_PER_CENT)
|
112
|
+
time = time_ago / SECS_PER_YEAR
|
113
|
+
time == 1 ? "a year" : "#{time_ago / SECS_PER_YEAR} years"
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
82
117
|
def datetime_or_text
|
83
118
|
timestamp ? format_datetime_string : text
|
84
119
|
end
|
@@ -18,7 +18,7 @@ type TitleDetailProps = {
|
|
18
18
|
title: string,
|
19
19
|
} & GlobalProps
|
20
20
|
|
21
|
-
const TitleDetail = (props: TitleDetailProps) => {
|
21
|
+
const TitleDetail = (props: TitleDetailProps): React.ReactElement => {
|
22
22
|
const {
|
23
23
|
align = "left",
|
24
24
|
aria = {},
|
@@ -37,19 +37,19 @@ const TitleDetail = (props: TitleDetailProps) => {
|
|
37
37
|
|
38
38
|
return (
|
39
39
|
<div
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
40
|
+
{...ariaProps}
|
41
|
+
{...dataProps}
|
42
|
+
{...htmlProps}
|
43
|
+
className={classnames(pbCss, globalProps(props), className)}
|
44
|
+
id={id}
|
45
45
|
>
|
46
46
|
<Title
|
47
|
-
|
48
|
-
|
47
|
+
size={4}
|
48
|
+
text={title}
|
49
49
|
/>
|
50
50
|
<Body
|
51
|
-
|
52
|
-
|
51
|
+
color="light"
|
52
|
+
text={detail}
|
53
53
|
/>
|
54
54
|
</div>
|
55
55
|
)
|
@@ -50,8 +50,8 @@ const Tooltip = forwardRef((props: TooltipProps, ref: ForwardedRef<unknown>): Re
|
|
50
50
|
...rest
|
51
51
|
} = props
|
52
52
|
|
53
|
-
const dataProps: { [key: string]:
|
54
|
-
const ariaProps: { [key: string]:
|
53
|
+
const dataProps: { [key: string]: string } = buildDataProps(data)
|
54
|
+
const ariaProps: { [key: string]: string } = buildAriaProps(aria)
|
55
55
|
const htmlProps = buildHtmlProps(htmlOptions)
|
56
56
|
|
57
57
|
const css = classnames(
|