playbook_ui 14.12.0.pre.alpha.play1887homeaddressfix5910 → 14.12.0.pre.alpha.playrailsinputmaskissue5933
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 +10 -3
- data/app/pb_kits/playbook/pb_advanced_table/Utilities/ActionBarAnimationHelper.ts +26 -0
- data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.scss +6 -6
- data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.tsx +34 -21
- data/app/pb_kits/playbook/pb_home_address_street/_home_address_street.tsx +7 -11
- data/app/pb_kits/playbook/pb_home_address_street/docs/example.yml +0 -2
- data/app/pb_kits/playbook/pb_home_address_street/docs/index.js +0 -1
- data/app/pb_kits/playbook/pb_home_address_street/home_address_street.rb +2 -13
- data/app/pb_kits/playbook/pb_text_input/docs/_text_input_mask.html.erb +1 -1
- data/app/pb_kits/playbook/pb_text_input/index.js +52 -83
- data/dist/chunks/{_typeahead-CkemExmL.js → _typeahead-qhstadx9.js} +1 -1
- data/dist/chunks/_weekday_stacked-CAHsfiaG.js +45 -0
- 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 +1 -1
- metadata +5 -8
- data/app/pb_kits/playbook/pb_home_address_street/docs/_home_address_street_formatting.html.erb +0 -11
- data/app/pb_kits/playbook/pb_home_address_street/docs/_home_address_street_formatting.jsx +0 -22
- data/app/pb_kits/playbook/pb_home_address_street/docs/_home_address_street_formatting_rails.md +0 -1
- data/app/pb_kits/playbook/pb_home_address_street/docs/_home_address_street_formatting_react.md +0 -1
- data/dist/chunks/_weekday_stacked-C2x2rHKi.js +0 -45
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5d0b37aeb1934fcd42145b3b00c5ccdb1d0d202320271ffb3f6cce025a8842c1
|
4
|
+
data.tar.gz: d4947bdab12110f001ddb7a4dccd6cb76632f77c5d834aa7ceb4c2ca3f090de9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ed89b4908906b35935f6dc4a95243dbcecc890b73cad32d5e91420d9ccaf762a4ab38fecb391b0c4c72af07d04222066a38b7e8a2c31881da1038457c91861b6
|
7
|
+
data.tar.gz: 07a73fd48069b741436c35ed29821d438f1f2114ff1d90eda9626ca2d6632fbf6a0c997eefe8398e0b37b1935fc929c45160e2a959574b7b4f400fd9195e7229
|
@@ -39,8 +39,15 @@ export const TableHeaderCell = ({
|
|
39
39
|
sortIcon,
|
40
40
|
table
|
41
41
|
}: TableHeaderCellProps) => {
|
42
|
-
const {
|
43
|
-
|
42
|
+
const {
|
43
|
+
sortControl,
|
44
|
+
responsive,
|
45
|
+
selectableRows,
|
46
|
+
hasAnySubRows,
|
47
|
+
showActionsBar,
|
48
|
+
inlineRowLoading,
|
49
|
+
isActionBarVisible,
|
50
|
+
} = useContext(AdvancedTableContext);
|
44
51
|
|
45
52
|
type justifyTypes = "none" | "center" | "start" | "end" | "between" | "around" | "evenly"
|
46
53
|
|
@@ -65,7 +72,7 @@ export const TableHeaderCell = ({
|
|
65
72
|
|
66
73
|
const cellClassName = classnames(
|
67
74
|
"table-header-cells",
|
68
|
-
`${showActionsBar && "header-cells-with-actions"}`,
|
75
|
+
`${showActionsBar && isActionBarVisible && "header-cells-with-actions"}`,
|
69
76
|
`${isChrome() ? "chrome-styles" : ""}`,
|
70
77
|
`${enableSorting ? "table-header-cells-active" : ""}`,
|
71
78
|
{ "pinned-left": responsive === "scroll" && isPinnedLeft },
|
@@ -0,0 +1,26 @@
|
|
1
|
+
export const showActionBar = (elem: HTMLElement) => {
|
2
|
+
elem.style.display = "block";
|
3
|
+
const height = elem.scrollHeight + "px";
|
4
|
+
elem.style.height = height;
|
5
|
+
elem.classList.add("is-visible");
|
6
|
+
elem.style.overflow = "hidden";
|
7
|
+
|
8
|
+
window.setTimeout(() => {
|
9
|
+
if (elem.classList.contains("is-visible")) {
|
10
|
+
elem.style.height = "";
|
11
|
+
elem.style.overflow = "visible";
|
12
|
+
}
|
13
|
+
}, 300);
|
14
|
+
};
|
15
|
+
|
16
|
+
export const hideActionBar = (elem: HTMLElement) => {
|
17
|
+
elem.style.height = elem.scrollHeight + "px";
|
18
|
+
elem.offsetHeight;
|
19
|
+
window.setTimeout(() => {
|
20
|
+
elem.style.height = "0";
|
21
|
+
elem.style.overflow = "hidden";
|
22
|
+
}, 10);
|
23
|
+
window.setTimeout(() => {
|
24
|
+
elem.classList.remove("is-visible");
|
25
|
+
}, 300);
|
26
|
+
};
|
@@ -31,12 +31,12 @@
|
|
31
31
|
width: 100%;
|
32
32
|
}
|
33
33
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
34
|
+
.row-selection-actions-card {
|
35
|
+
border-bottom-right-radius: 0px !important;
|
36
|
+
border-bottom-left-radius: 0px !important;
|
37
|
+
border-bottom-color: transparent;
|
38
|
+
transition: height 300ms ease;
|
39
|
+
}
|
40
40
|
.table-header-cells:first-child {
|
41
41
|
min-width: 180px;
|
42
42
|
}
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import React, { useState, useEffect, useCallback } from "react"
|
1
|
+
import React, { useState, useEffect, useCallback, useRef } from "react"
|
2
2
|
import classnames from "classnames"
|
3
3
|
|
4
4
|
import { GenericObject } from "../types"
|
@@ -27,6 +27,7 @@ import FlexItem from "../pb_flex/_flex_item"
|
|
27
27
|
import AdvancedTableContext from "./Context/AdvancedTableContext"
|
28
28
|
|
29
29
|
import { updateExpandAndCollapseState } from "./Utilities/ExpansionControlHelpers"
|
30
|
+
import { showActionBar, hideActionBar } from "./Utilities/ActionBarAnimationHelper"
|
30
31
|
|
31
32
|
import { CustomCell } from "./Components/CustomCell"
|
32
33
|
import { TableHeader } from "./SubKits/TableHeader"
|
@@ -295,6 +296,20 @@ const AdvancedTable = (props: AdvancedTableProps) => {
|
|
295
296
|
const onPageChange = (page: number) => {
|
296
297
|
table.setPageIndex(page - 1)
|
297
298
|
}
|
299
|
+
//When to show the actions bar as a whole
|
300
|
+
const isActionBarVisible = selectableRows && showActionsBar && selectedRowsLength > 0
|
301
|
+
|
302
|
+
//Ref and useEffect for animating the actions bar
|
303
|
+
const cardRef = useRef(null);
|
304
|
+
useEffect(() => {
|
305
|
+
if (cardRef.current) {
|
306
|
+
if (isActionBarVisible) {
|
307
|
+
showActionBar(cardRef.current);
|
308
|
+
} else {
|
309
|
+
hideActionBar(cardRef.current);
|
310
|
+
}
|
311
|
+
}
|
312
|
+
}, [isActionBarVisible]);
|
298
313
|
|
299
314
|
return (
|
300
315
|
<div {...ariaProps}
|
@@ -311,6 +326,7 @@ const AdvancedTable = (props: AdvancedTableProps) => {
|
|
311
326
|
expandedControl,
|
312
327
|
handleExpandOrCollapse,
|
313
328
|
inlineRowLoading,
|
329
|
+
isActionBarVisible,
|
314
330
|
loading,
|
315
331
|
responsive,
|
316
332
|
setExpanded,
|
@@ -333,27 +349,24 @@ const AdvancedTable = (props: AdvancedTableProps) => {
|
|
333
349
|
total={table.getPageCount()}
|
334
350
|
/>
|
335
351
|
}
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
352
|
+
<Card
|
353
|
+
borderNone={!isActionBarVisible}
|
354
|
+
className={`${isActionBarVisible && "show-action-card row-selection-actions-card"}`}
|
355
|
+
htmlOptions={{ ref: cardRef as any }}
|
356
|
+
padding={`${isActionBarVisible ? "xs" : "none"}`}
|
357
|
+
>
|
358
|
+
<Flex alignItems="center"
|
359
|
+
justify="between"
|
360
|
+
>
|
361
|
+
<Caption color="light"
|
362
|
+
paddingLeft="xs"
|
363
|
+
size="xs"
|
340
364
|
>
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
size="xs"
|
347
|
-
>
|
348
|
-
{selectedRowsLength} Selected
|
349
|
-
</Caption>
|
350
|
-
<FlexItem>
|
351
|
-
{actions}
|
352
|
-
</FlexItem>
|
353
|
-
</Flex>
|
354
|
-
</Card>
|
355
|
-
)
|
356
|
-
}
|
365
|
+
{selectedRowsLength} Selected
|
366
|
+
</Caption>
|
367
|
+
<FlexItem>{actions}</FlexItem>
|
368
|
+
</Flex>
|
369
|
+
</Card>
|
357
370
|
<Table
|
358
371
|
className={`${loading ? "content-loading" : ""}`}
|
359
372
|
dark={dark}
|
@@ -18,7 +18,6 @@ type HomeAddressStreetProps = {
|
|
18
18
|
className?: string,
|
19
19
|
data?: { [key: string]: string },
|
20
20
|
dark?: boolean,
|
21
|
-
preserveCase?: boolean,
|
22
21
|
emphasis: "street" | "city" | "none",
|
23
22
|
htmlOptions?: {[key: string]: string | number | boolean | (() => void)},
|
24
23
|
homeId: string,
|
@@ -44,7 +43,6 @@ const HomeAddressStreet = (props: HomeAddressStreetProps): React.ReactElement =>
|
|
44
43
|
htmlOptions = {},
|
45
44
|
homeId,
|
46
45
|
homeUrl,
|
47
|
-
preserveCase = false,
|
48
46
|
target,
|
49
47
|
newWindow,
|
50
48
|
houseStyle,
|
@@ -79,8 +77,6 @@ const HomeAddressStreet = (props: HomeAddressStreetProps): React.ReactElement =>
|
|
79
77
|
return null
|
80
78
|
}
|
81
79
|
|
82
|
-
const formatStreetAdr = (address: string): string => preserveCase ? address : titleize(address)
|
83
|
-
|
84
80
|
return (
|
85
81
|
<div
|
86
82
|
className={classes(className, dark)}
|
@@ -95,7 +91,7 @@ const HomeAddressStreet = (props: HomeAddressStreetProps): React.ReactElement =>
|
|
95
91
|
dark={dark}
|
96
92
|
size={4}
|
97
93
|
>
|
98
|
-
{joinPresent([
|
94
|
+
{joinPresent([titleize(address), houseStyle], ' · ')}
|
99
95
|
</Title>
|
100
96
|
<Title
|
101
97
|
className="pb_home_address_street_address"
|
@@ -105,14 +101,14 @@ const HomeAddressStreet = (props: HomeAddressStreetProps): React.ReactElement =>
|
|
105
101
|
{titleize(addressCont)}
|
106
102
|
</Title>
|
107
103
|
<Body color="light">
|
108
|
-
{`${titleize(city)}, ${state
|
104
|
+
{`${titleize(city)}, ${state} ${zipcode}`}
|
109
105
|
</Body>
|
110
106
|
</div>
|
111
107
|
}
|
112
108
|
{emphasis == 'city' &&
|
113
109
|
<div>
|
114
110
|
<Body color="light">
|
115
|
-
{joinPresent([
|
111
|
+
{joinPresent([titleize(address), houseStyle], ' · ')}
|
116
112
|
</Body>
|
117
113
|
<Body color="light">{titleize(addressCont)}</Body>
|
118
114
|
<div>
|
@@ -122,7 +118,7 @@ const HomeAddressStreet = (props: HomeAddressStreetProps): React.ReactElement =>
|
|
122
118
|
size={4}
|
123
119
|
tag="span"
|
124
120
|
>
|
125
|
-
{`${titleize(city)}, ${state
|
121
|
+
{`${titleize(city)}, ${state}`}
|
126
122
|
</Title>
|
127
123
|
<Body
|
128
124
|
color="light"
|
@@ -136,15 +132,15 @@ const HomeAddressStreet = (props: HomeAddressStreetProps): React.ReactElement =>
|
|
136
132
|
{emphasis == 'none' &&
|
137
133
|
<div>
|
138
134
|
<Body dark={dark}>
|
139
|
-
{joinPresent([
|
135
|
+
{joinPresent([titleize(address), houseStyle], ' · ')}
|
140
136
|
</Body>
|
141
|
-
<Body dark={dark}>{
|
137
|
+
<Body dark={dark}>{titleize(addressCont)}</Body>
|
142
138
|
<div>
|
143
139
|
<Body
|
144
140
|
color="light"
|
145
141
|
dark={dark}
|
146
142
|
>
|
147
|
-
{`${titleize(city)}, ${state
|
143
|
+
{`${titleize(city)}, ${state} ${zipcode}`}
|
148
144
|
</Body>
|
149
145
|
</div>
|
150
146
|
</div>
|
@@ -5,14 +5,12 @@ examples:
|
|
5
5
|
- home_address_street_emphasis: Emphasis
|
6
6
|
- home_address_street_modified: Modified
|
7
7
|
- home_address_street_link: Link
|
8
|
-
- home_address_street_formatting: Formatting
|
9
8
|
|
10
9
|
react:
|
11
10
|
- home_address_street_default: Default
|
12
11
|
- home_address_street_emphasis: Emphasis
|
13
12
|
- home_address_street_modified: Modified
|
14
13
|
- home_address_street_link: Link
|
15
|
-
- home_address_street_formatting: Formatting
|
16
14
|
|
17
15
|
swift:
|
18
16
|
- home_address_street_default_swift: Default
|
@@ -2,4 +2,3 @@ export { default as HomeAddressStreetDefault } from './_home_address_street_defa
|
|
2
2
|
export { default as HomeAddressStreetEmphasis } from './_home_address_street_emphasis.jsx'
|
3
3
|
export { default as HomeAddressStreetModified } from './_home_address_street_modified.jsx'
|
4
4
|
export { default as HomeAddressStreetLink } from './_home_address_street_link.jsx'
|
5
|
-
export { default as HomeAddressStreetFormatting } from './_home_address_street_formatting.jsx'
|
@@ -18,7 +18,6 @@ module Playbook
|
|
18
18
|
prop :state
|
19
19
|
prop :zipcode
|
20
20
|
prop :territory
|
21
|
-
prop :preserve_case, default: false
|
22
21
|
prop :dark, type: Playbook::Props::Boolean, default: false
|
23
22
|
|
24
23
|
def classname
|
@@ -30,7 +29,7 @@ module Playbook
|
|
30
29
|
end
|
31
30
|
|
32
31
|
def city_state
|
33
|
-
[city&.titleize, state
|
32
|
+
[city&.titleize, state].join(", ")
|
34
33
|
end
|
35
34
|
|
36
35
|
def zip
|
@@ -38,7 +37,7 @@ module Playbook
|
|
38
37
|
end
|
39
38
|
|
40
39
|
def address_house_style
|
41
|
-
[
|
40
|
+
[address&.titleize, house_style].join(separator)
|
42
41
|
end
|
43
42
|
|
44
43
|
def address_house_style2
|
@@ -49,16 +48,6 @@ module Playbook
|
|
49
48
|
house_style ? " \u00b7 " : ""
|
50
49
|
end
|
51
50
|
|
52
|
-
def format_street_address
|
53
|
-
preserve_case ? address : custom_titleize(address)
|
54
|
-
end
|
55
|
-
|
56
|
-
def custom_titleize(str)
|
57
|
-
return "" if str.nil?
|
58
|
-
|
59
|
-
str.split(" ").map(&:capitalize).join(" ")
|
60
|
-
end
|
61
|
-
|
62
51
|
def city_emphasis_props
|
63
52
|
{
|
64
53
|
address_house_style: address_house_style,
|
@@ -1,102 +1,71 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
const inputElements = document.querySelectorAll('[data-pb-input-mask="true"]');
|
4
|
-
|
5
|
-
inputElements.forEach((inputElement) => {
|
6
|
-
inputElement.addEventListener("input", (event) => {
|
7
|
-
const maskType = inputElement.getAttribute("mask");
|
8
|
-
const cursorPosition = inputElement.selectionStart;
|
9
|
-
|
10
|
-
let rawValue = event.target.value;
|
11
|
-
let formattedValue = rawValue;
|
12
|
-
|
13
|
-
// Apply formatting based on the mask type
|
14
|
-
switch (maskType) {
|
15
|
-
case "currency":
|
16
|
-
formattedValue = formatCurrency(rawValue);
|
17
|
-
break;
|
18
|
-
case "ssn":
|
19
|
-
formattedValue = formatSSN(rawValue);
|
20
|
-
break;
|
21
|
-
case "postal_code":
|
22
|
-
formattedValue = formatPostalCode(rawValue);
|
23
|
-
break;
|
24
|
-
case "zip_code":
|
25
|
-
formattedValue = formatZipCode(rawValue);
|
26
|
-
break;
|
27
|
-
}
|
28
|
-
|
29
|
-
// Update the sanitized input field in the same wrapper
|
30
|
-
const sanitizedInput = inputElement
|
31
|
-
.closest(".text_input_wrapper")
|
32
|
-
?.querySelector('[data="sanitized-pb-input"]');
|
33
|
-
|
34
|
-
if (sanitizedInput) {
|
35
|
-
switch (maskType) {
|
36
|
-
case "ssn":
|
37
|
-
sanitizedInput.value = sanitizeSSN(formattedValue);
|
38
|
-
break;
|
39
|
-
case "currency":
|
40
|
-
sanitizedInput.value = sanitizeCurrency(formattedValue);
|
41
|
-
break;
|
42
|
-
default:
|
43
|
-
sanitizedInput.value = formattedValue;
|
44
|
-
}
|
45
|
-
}
|
46
|
-
|
47
|
-
inputElement.value = formattedValue;
|
48
|
-
setCursorPosition(inputElement, cursorPosition, rawValue, formattedValue);
|
49
|
-
});
|
50
|
-
});
|
1
|
+
import PbEnhancedElement from "../pb_enhanced_element"
|
2
|
+
import { INPUTMASKS } from "./inputMask"
|
51
3
|
|
4
|
+
export default class PbTextInput extends PbEnhancedElement {
|
5
|
+
static get selector() {
|
6
|
+
return '[data-pb-input-mask="true"]';
|
52
7
|
}
|
53
|
-
}
|
54
|
-
|
55
|
-
function formatCurrency(value) {
|
56
|
-
const numericValue = value.replace(/[^0-9]/g, "").slice(0, 15);
|
57
|
-
|
58
|
-
if (!numericValue) return "";
|
59
|
-
|
60
|
-
const dollars = parseFloat((parseInt(numericValue) / 100).toFixed(2));
|
61
|
-
if (dollars === 0) return "";
|
62
8
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
}
|
68
|
-
}
|
69
|
-
|
70
|
-
function formatSSN(value) {
|
71
|
-
const cleaned = value.replace(/\D/g, "").slice(0, 9);
|
72
|
-
return cleaned
|
73
|
-
.replace(/(\d{5})(?=\d)/, "$1-")
|
74
|
-
.replace(/(\d{3})(?=\d)/, "$1-");
|
75
|
-
}
|
9
|
+
connect() {
|
10
|
+
this.handleInput = this.handleInput.bind(this);
|
11
|
+
this.element.addEventListener("input", this.handleInput);
|
12
|
+
this.handleInput();
|
13
|
+
}
|
76
14
|
|
77
|
-
|
78
|
-
|
79
|
-
}
|
15
|
+
disconnect() {
|
16
|
+
this.element.removeEventListener("input", this.handleInput);
|
17
|
+
}
|
80
18
|
|
81
|
-
|
82
|
-
|
83
|
-
|
19
|
+
handleInput() {
|
20
|
+
const maskType = this.element.getAttribute("mask");
|
21
|
+
const cursorPosition = this.element.selectionStart;
|
22
|
+
const rawValue = this.element.value;
|
23
|
+
let formattedValue = rawValue;
|
24
|
+
|
25
|
+
const maskKey = {
|
26
|
+
currency: 'currency',
|
27
|
+
ssn: 'ssn',
|
28
|
+
postal_code: 'postalCode',
|
29
|
+
zip_code: 'zipCode',
|
30
|
+
}[maskType];
|
31
|
+
|
32
|
+
if (maskKey && INPUTMASKS[maskKey]) {
|
33
|
+
formattedValue = INPUTMASKS[maskKey].format(rawValue);
|
34
|
+
}
|
35
|
+
|
36
|
+
const sanitizedInput = this.element
|
37
|
+
.closest(".text_input_wrapper")
|
38
|
+
?.querySelector('[data="sanitized-pb-input"]');
|
39
|
+
|
40
|
+
if (sanitizedInput) {
|
41
|
+
switch (maskType) {
|
42
|
+
case "ssn":
|
43
|
+
sanitizedInput.value = sanitizeSSN(formattedValue);
|
44
|
+
break;
|
45
|
+
case "currency":
|
46
|
+
sanitizedInput.value = sanitizeCurrency(formattedValue);
|
47
|
+
break;
|
48
|
+
default:
|
49
|
+
sanitizedInput.value = formattedValue;
|
50
|
+
}
|
51
|
+
}
|
52
|
+
|
53
|
+
this.element.value = formattedValue;
|
54
|
+
setCursorPosition(this.element, cursorPosition, rawValue, formattedValue);
|
55
|
+
}
|
84
56
|
}
|
85
57
|
|
86
58
|
function sanitizeSSN(input) {
|
87
|
-
return input.replace(/\D/g, "");
|
59
|
+
return input.replace(/\D/g, "");
|
88
60
|
}
|
89
61
|
|
90
62
|
function sanitizeCurrency(input) {
|
91
|
-
return input.replace(/[$,]/g, "");
|
63
|
+
return input.replace(/[$,]/g, "");
|
92
64
|
}
|
93
65
|
|
94
|
-
// function to set cursor position
|
95
66
|
function setCursorPosition(inputElement, cursorPosition, rawValue, formattedValue) {
|
96
67
|
const difference = formattedValue.length - rawValue.length;
|
97
|
-
|
98
68
|
const newPosition = Math.max(0, cursorPosition + difference);
|
99
|
-
|
100
69
|
requestAnimationFrame(() => {
|
101
70
|
inputElement.setSelectionRange(newPosition, newPosition);
|
102
71
|
});
|