playbook_ui 14.9.0.pre.alpha.play1703errorstatealignment4889 → 14.9.0.pre.alpha.play1703errorstatealignment4991
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/pb_kits/playbook/pb_bar_graph/docs/_bar_graph_custom.jsx +53 -49
- data/app/pb_kits/playbook/pb_bar_graph/docs/_bar_graph_custom_rails.html.erb +29 -36
- data/app/pb_kits/playbook/pb_collapsible/_collapsible.tsx +9 -4
- data/app/pb_kits/playbook/pb_collapsible/child_kits/CollapsibleContent.tsx +2 -2
- data/app/pb_kits/playbook/pb_collapsible/child_kits/CollapsibleMain.tsx +2 -2
- data/app/pb_kits/playbook/pb_form_group/_error_state_mixin.scss +49 -0
- data/app/pb_kits/playbook/pb_form_group/_form_group.scss +46 -12
- data/app/pb_kits/playbook/pb_link/_link.scss +3 -3
- data/app/pb_kits/playbook/pb_table/docs/_table_with_collapsible.jsx +75 -0
- data/app/pb_kits/playbook/pb_table/docs/_table_with_collapsible.md +1 -0
- data/app/pb_kits/playbook/pb_table/docs/_table_with_collapsible_with_custom_click.jsx +108 -0
- data/app/pb_kits/playbook/pb_table/docs/_table_with_collapsible_with_custom_click.md +2 -0
- data/app/pb_kits/playbook/pb_table/docs/_table_with_collapsible_with_custom_content.jsx +94 -0
- data/app/pb_kits/playbook/pb_table/docs/_table_with_collapsible_with_custom_content.md +0 -0
- data/app/pb_kits/playbook/pb_table/docs/_table_with_collapsible_with_nested_rows.jsx +83 -0
- data/app/pb_kits/playbook/pb_table/docs/_table_with_collapsible_with_nested_rows.md +3 -0
- data/app/pb_kits/playbook/pb_table/docs/_table_with_collapsible_with_nested_table.jsx +120 -0
- data/app/pb_kits/playbook/pb_table/docs/_table_with_collapsible_with_nested_table.md +1 -0
- data/app/pb_kits/playbook/pb_table/docs/example.yml +5 -0
- data/app/pb_kits/playbook/pb_table/docs/index.js +5 -0
- data/app/pb_kits/playbook/pb_table/styles/_all.scss +2 -1
- data/app/pb_kits/playbook/pb_table/styles/_collapsible.scss +35 -0
- data/app/pb_kits/playbook/pb_table/subcomponents/_table_row.tsx +106 -1
- data/app/pb_kits/playbook/pb_text_input/_text_input.tsx +35 -3
- data/app/pb_kits/playbook/pb_text_input/docs/_text_input_mask.jsx +88 -0
- data/app/pb_kits/playbook/pb_text_input/docs/example.yml +1 -0
- data/app/pb_kits/playbook/pb_text_input/docs/index.js +1 -0
- data/app/pb_kits/playbook/pb_text_input/inputMask.ts +64 -0
- data/app/pb_kits/playbook/pb_text_input/text_input.test.js +139 -2
- data/dist/chunks/_typeahead-l1kq1p9m.js +22 -0
- data/dist/chunks/_weekday_stacked-B28kYXl9.js +45 -0
- data/dist/chunks/{lib-CVPInSs5.js → lib-CuCy3_xO.js} +3 -3
- data/dist/chunks/{pb_form_validation-CDLJ5eAG.js → pb_form_validation-D37k10a0.js} +1 -1
- data/dist/chunks/vendor.js +1 -1
- data/dist/menu.yml +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 +20 -6
- data/dist/chunks/_typeahead-4sdDeM4X.js +0 -22
- data/dist/chunks/_weekday_stacked-CblTZ9cd.js +0 -45
@@ -0,0 +1,94 @@
|
|
1
|
+
import React from 'react'
|
2
|
+
import { Table, Icon, Card, Body, Image, Flex } from 'playbook-ui'
|
3
|
+
|
4
|
+
const TableWithCollapsibleWithCustomContent = (props) => {
|
5
|
+
|
6
|
+
const Content = () => {
|
7
|
+
return (
|
8
|
+
<Card
|
9
|
+
borderNone
|
10
|
+
borderRadius="none"
|
11
|
+
color="light"
|
12
|
+
paddingX="xl"
|
13
|
+
paddingY="md"
|
14
|
+
{...props}
|
15
|
+
>
|
16
|
+
<Body paddingBottom="sm"
|
17
|
+
text="Expanded Custom Layout"
|
18
|
+
{...props}
|
19
|
+
/>
|
20
|
+
<Flex justify="between">
|
21
|
+
<Image
|
22
|
+
url="https://via.placeholder.com/150"
|
23
|
+
/>
|
24
|
+
<Image
|
25
|
+
url="https://via.placeholder.com/150"
|
26
|
+
/>
|
27
|
+
<Image
|
28
|
+
url="https://via.placeholder.com/150"
|
29
|
+
/>
|
30
|
+
<Image
|
31
|
+
url="https://via.placeholder.com/150"
|
32
|
+
/>
|
33
|
+
</Flex>
|
34
|
+
</Card>
|
35
|
+
);
|
36
|
+
};
|
37
|
+
|
38
|
+
return (
|
39
|
+
<Table
|
40
|
+
size="sm"
|
41
|
+
{...props}
|
42
|
+
>
|
43
|
+
<Table.Head>
|
44
|
+
<Table.Row>
|
45
|
+
<Table.Header>{'Column 1'}</Table.Header>
|
46
|
+
<Table.Header>{'Column 2'}</Table.Header>
|
47
|
+
<Table.Header>{'Column 3'}</Table.Header>
|
48
|
+
<Table.Header>{'Column 4'}</Table.Header>
|
49
|
+
<Table.Header>{'Column 5'}</Table.Header>
|
50
|
+
<Table.Header>{''}</Table.Header>
|
51
|
+
</Table.Row>
|
52
|
+
|
53
|
+
</Table.Head>
|
54
|
+
<Table.Body>
|
55
|
+
<Table.Row collapsible
|
56
|
+
collapsibleContent={<Content/>}
|
57
|
+
{...props}
|
58
|
+
>
|
59
|
+
<Table.Cell>{'Value 1'}</Table.Cell>
|
60
|
+
<Table.Cell>{'Value 2'}</Table.Cell>
|
61
|
+
<Table.Cell>{'Value 3'}</Table.Cell>
|
62
|
+
<Table.Cell>{'Value 4'}</Table.Cell>
|
63
|
+
<Table.Cell>{'Value 5'}</Table.Cell>
|
64
|
+
<Table.Cell textAlign="right">{
|
65
|
+
<Icon
|
66
|
+
color="primary"
|
67
|
+
fixedWidth
|
68
|
+
icon="chevron-down"
|
69
|
+
/>}
|
70
|
+
</Table.Cell>
|
71
|
+
|
72
|
+
</Table.Row>
|
73
|
+
<Table.Row>
|
74
|
+
<Table.Cell>{'Value 1'}</Table.Cell>
|
75
|
+
<Table.Cell>{'Value 2'}</Table.Cell>
|
76
|
+
<Table.Cell>{'Value 3'}</Table.Cell>
|
77
|
+
<Table.Cell>{'Value 4'}</Table.Cell>
|
78
|
+
<Table.Cell>{'Value 5'}</Table.Cell>
|
79
|
+
<Table.Cell>{''}</Table.Cell>
|
80
|
+
</Table.Row>
|
81
|
+
<Table.Row>
|
82
|
+
<Table.Cell>{'Value 1'}</Table.Cell>
|
83
|
+
<Table.Cell>{'Value 2'}</Table.Cell>
|
84
|
+
<Table.Cell>{'Value 3'}</Table.Cell>
|
85
|
+
<Table.Cell>{'Value 4'}</Table.Cell>
|
86
|
+
<Table.Cell>{'Value 5'}</Table.Cell>
|
87
|
+
<Table.Cell>{''}</Table.Cell>
|
88
|
+
</Table.Row>
|
89
|
+
</Table.Body>
|
90
|
+
</Table>
|
91
|
+
)
|
92
|
+
}
|
93
|
+
|
94
|
+
export default TableWithCollapsibleWithCustomContent
|
File without changes
|
@@ -0,0 +1,83 @@
|
|
1
|
+
import React from 'react'
|
2
|
+
import { Table, Background, Icon } from 'playbook-ui'
|
3
|
+
|
4
|
+
const TableWithCollapsibleWithNestedRows = (props) => {
|
5
|
+
|
6
|
+
const Content = () => {
|
7
|
+
return (
|
8
|
+
<Table
|
9
|
+
borderRadius="none"
|
10
|
+
container={false}
|
11
|
+
size="sm"
|
12
|
+
{...props}
|
13
|
+
>
|
14
|
+
<Background tag="tr"
|
15
|
+
{...props}
|
16
|
+
>
|
17
|
+
<Table.Cell>Expanded</Table.Cell>
|
18
|
+
<Table.Cell>Expanded</Table.Cell>
|
19
|
+
<Table.Cell>Expanded</Table.Cell>
|
20
|
+
<Table.Cell>Expanded</Table.Cell>
|
21
|
+
<Table.Cell>Expanded</Table.Cell>
|
22
|
+
</Background>
|
23
|
+
</Table>
|
24
|
+
);
|
25
|
+
};
|
26
|
+
|
27
|
+
return (
|
28
|
+
<Table
|
29
|
+
size="sm"
|
30
|
+
{...props}
|
31
|
+
>
|
32
|
+
<Table.Head>
|
33
|
+
<Table.Row>
|
34
|
+
<Table.Header>{'Column 1'}</Table.Header>
|
35
|
+
<Table.Header>{'Column 2'}</Table.Header>
|
36
|
+
<Table.Header>{'Column 3'}</Table.Header>
|
37
|
+
<Table.Header>{'Column 4'}</Table.Header>
|
38
|
+
<Table.Header>{'Column 5'}</Table.Header>
|
39
|
+
<Table.Header>{''}</Table.Header>
|
40
|
+
</Table.Row>
|
41
|
+
|
42
|
+
</Table.Head>
|
43
|
+
<Table.Body>
|
44
|
+
<Table.Row collapsible
|
45
|
+
collapsibleContent={<Content/>}
|
46
|
+
collapsibleSideHighlight={false}
|
47
|
+
>
|
48
|
+
<Table.Cell>{'Value 1'}</Table.Cell>
|
49
|
+
<Table.Cell>{'Value 2'}</Table.Cell>
|
50
|
+
<Table.Cell>{'Value 3'}</Table.Cell>
|
51
|
+
<Table.Cell>{'Value 4'}</Table.Cell>
|
52
|
+
<Table.Cell>{'Value 5'}</Table.Cell>
|
53
|
+
<Table.Cell textAlign="right">{
|
54
|
+
<Icon
|
55
|
+
color="primary"
|
56
|
+
fixedWidth
|
57
|
+
icon="chevron-down"
|
58
|
+
/>}
|
59
|
+
</Table.Cell>
|
60
|
+
|
61
|
+
</Table.Row>
|
62
|
+
<Table.Row>
|
63
|
+
<Table.Cell>{'Value 1'}</Table.Cell>
|
64
|
+
<Table.Cell>{'Value 2'}</Table.Cell>
|
65
|
+
<Table.Cell>{'Value 3'}</Table.Cell>
|
66
|
+
<Table.Cell>{'Value 4'}</Table.Cell>
|
67
|
+
<Table.Cell>{'Value 5'}</Table.Cell>
|
68
|
+
<Table.Cell>{''}</Table.Cell>
|
69
|
+
</Table.Row>
|
70
|
+
<Table.Row>
|
71
|
+
<Table.Cell>{'Value 1'}</Table.Cell>
|
72
|
+
<Table.Cell>{'Value 2'}</Table.Cell>
|
73
|
+
<Table.Cell>{'Value 3'}</Table.Cell>
|
74
|
+
<Table.Cell>{'Value 4'}</Table.Cell>
|
75
|
+
<Table.Cell>{'Value 5'}</Table.Cell>
|
76
|
+
<Table.Cell>{''}</Table.Cell>
|
77
|
+
</Table.Row>
|
78
|
+
</Table.Body>
|
79
|
+
</Table>
|
80
|
+
)
|
81
|
+
}
|
82
|
+
|
83
|
+
export default TableWithCollapsibleWithNestedRows
|
@@ -0,0 +1,120 @@
|
|
1
|
+
import React from 'react'
|
2
|
+
import {Pill, Background, Table, Icon} from "playbook-ui"
|
3
|
+
|
4
|
+
const TableWithCollapsibleWithNestedTable = (props) => {
|
5
|
+
|
6
|
+
const Content = () => {
|
7
|
+
return (
|
8
|
+
<Table
|
9
|
+
borderRadius="none"
|
10
|
+
container={false}
|
11
|
+
size="sm"
|
12
|
+
{...props}
|
13
|
+
>
|
14
|
+
<Table.Head>
|
15
|
+
<Background
|
16
|
+
tag="tr"
|
17
|
+
{...props}
|
18
|
+
>
|
19
|
+
<Table.Header>{"Alt Header"}</Table.Header>
|
20
|
+
<Table.Header>{"Alt Header"}</Table.Header>
|
21
|
+
<Table.Header>{"Alt Header"}</Table.Header>
|
22
|
+
<Table.Header>{"Alt Header"}</Table.Header>
|
23
|
+
</Background>
|
24
|
+
</Table.Head>
|
25
|
+
<Table.Body>
|
26
|
+
<Table.Row>
|
27
|
+
<Table.Cell>{"Expanded"}</Table.Cell>
|
28
|
+
<Table.Cell>{"Expanded"}</Table.Cell>
|
29
|
+
<Table.Cell>{"Expanded"}</Table.Cell>
|
30
|
+
<Table.Cell>
|
31
|
+
<Pill text="Pill"
|
32
|
+
variant="primary"
|
33
|
+
{...props}
|
34
|
+
/>
|
35
|
+
</Table.Cell>
|
36
|
+
</Table.Row>
|
37
|
+
<Table.Row>
|
38
|
+
<Table.Cell>{"Expanded"}</Table.Cell>
|
39
|
+
<Table.Cell>{"Expanded"}</Table.Cell>
|
40
|
+
<Table.Cell>{"Expanded"}</Table.Cell>
|
41
|
+
<Table.Cell>
|
42
|
+
<Pill text="Pill"
|
43
|
+
variant="primary"
|
44
|
+
{...props}
|
45
|
+
/>
|
46
|
+
</Table.Cell>
|
47
|
+
</Table.Row>
|
48
|
+
<Table.Row>
|
49
|
+
<Table.Cell>{"Expanded"}</Table.Cell>
|
50
|
+
<Table.Cell>{"Expanded"}</Table.Cell>
|
51
|
+
<Table.Cell>{"Expanded"}</Table.Cell>
|
52
|
+
<Table.Cell>
|
53
|
+
<Pill text="Pill"
|
54
|
+
variant="primary"
|
55
|
+
{...props}
|
56
|
+
/>
|
57
|
+
</Table.Cell>
|
58
|
+
</Table.Row>
|
59
|
+
</Table.Body>
|
60
|
+
</Table>
|
61
|
+
);
|
62
|
+
};
|
63
|
+
|
64
|
+
return (
|
65
|
+
<Table
|
66
|
+
size="sm"
|
67
|
+
{...props}
|
68
|
+
>
|
69
|
+
<Table.Head>
|
70
|
+
<Table.Row>
|
71
|
+
<Table.Header>{'Column 1'}</Table.Header>
|
72
|
+
<Table.Header>{'Column 2'}</Table.Header>
|
73
|
+
<Table.Header>{'Column 3'}</Table.Header>
|
74
|
+
<Table.Header>{'Column 4'}</Table.Header>
|
75
|
+
<Table.Header>{'Column 5'}</Table.Header>
|
76
|
+
<Table.Header>{''}</Table.Header>
|
77
|
+
</Table.Row>
|
78
|
+
|
79
|
+
</Table.Head>
|
80
|
+
<Table.Body>
|
81
|
+
<Table.Row collapsible
|
82
|
+
collapsibleContent={<Content/>}
|
83
|
+
collapsibleSideHighlight={false}
|
84
|
+
>
|
85
|
+
<Table.Cell>{'Value 1'}</Table.Cell>
|
86
|
+
<Table.Cell>{'Value 2'}</Table.Cell>
|
87
|
+
<Table.Cell>{'Value 3'}</Table.Cell>
|
88
|
+
<Table.Cell>{'Value 4'}</Table.Cell>
|
89
|
+
<Table.Cell>{'Value 5'}</Table.Cell>
|
90
|
+
<Table.Cell textAlign="right">{
|
91
|
+
<Icon
|
92
|
+
color="primary"
|
93
|
+
fixedWidth
|
94
|
+
icon="chevron-down"
|
95
|
+
/>}
|
96
|
+
</Table.Cell>
|
97
|
+
|
98
|
+
</Table.Row>
|
99
|
+
<Table.Row>
|
100
|
+
<Table.Cell>{'Value 1'}</Table.Cell>
|
101
|
+
<Table.Cell>{'Value 2'}</Table.Cell>
|
102
|
+
<Table.Cell>{'Value 3'}</Table.Cell>
|
103
|
+
<Table.Cell>{'Value 4'}</Table.Cell>
|
104
|
+
<Table.Cell>{'Value 5'}</Table.Cell>
|
105
|
+
<Table.Cell>{''}</Table.Cell>
|
106
|
+
</Table.Row>
|
107
|
+
<Table.Row>
|
108
|
+
<Table.Cell>{'Value 1'}</Table.Cell>
|
109
|
+
<Table.Cell>{'Value 2'}</Table.Cell>
|
110
|
+
<Table.Cell>{'Value 3'}</Table.Cell>
|
111
|
+
<Table.Cell>{'Value 4'}</Table.Cell>
|
112
|
+
<Table.Cell>{'Value 5'}</Table.Cell>
|
113
|
+
<Table.Cell>{''}</Table.Cell>
|
114
|
+
</Table.Row>
|
115
|
+
</Table.Body>
|
116
|
+
</Table>
|
117
|
+
)
|
118
|
+
}
|
119
|
+
|
120
|
+
export default TableWithCollapsibleWithNestedTable
|
@@ -0,0 +1 @@
|
|
1
|
+
The `collapsibleContent` can also be used to display nested Tables within each Row.
|
@@ -55,3 +55,8 @@ examples:
|
|
55
55
|
- table_with_subcomponents: Table with Sub Components (Table Elements)
|
56
56
|
- table_with_subcomponents_as_divs: Table with Sub Components (Divs)
|
57
57
|
- table_outer_padding: Outer Padding
|
58
|
+
- table_with_collapsible: Table with Collapsible
|
59
|
+
- table_with_collapsible_with_custom_click: Table with Collapsible with Custom Click
|
60
|
+
- table_with_collapsible_with_custom_content: Table with Collapsible with Custom Content
|
61
|
+
- table_with_collapsible_with_nested_rows: Table with Collapsible with Nested Rows
|
62
|
+
- table_with_collapsible_with_nested_table: Table with Collapsible with Nested Table
|
@@ -26,3 +26,8 @@ export { default as TableWithSubcomponents } from './_table_with_subcomponents.j
|
|
26
26
|
export { default as TableWithSubcomponentsAsDivs } from './_table_with_subcomponents_as_divs.jsx'
|
27
27
|
export { default as TableOuterPadding } from './_table_outer_padding.jsx'
|
28
28
|
export { default as TableStickyLeftColumns } from './_table_sticky_left_columns.jsx'
|
29
|
+
export { default as TableWithCollapsible } from './_table_with_collapsible.jsx'
|
30
|
+
export { default as TableWithCollapsibleWithCustomContent } from './_table_with_collapsible_with_custom_content.jsx'
|
31
|
+
export { default as TableWithCollapsibleWithNestedTable } from './_table_with_collapsible_with_nested_table.jsx'
|
32
|
+
export { default as TableWithCollapsibleWithNestedRows } from './_table_with_collapsible_with_nested_rows.jsx'
|
33
|
+
export { default as TableWithCollapsibleWithCustomClick } from './_table_with_collapsible_with_custom_click.jsx'
|
@@ -0,0 +1,35 @@
|
|
1
|
+
@import "../../tokens/colors";
|
2
|
+
|
3
|
+
.table_collapsible_side_highlight {
|
4
|
+
border-left: 4px solid $primary;
|
5
|
+
&.dark {
|
6
|
+
border-left: 4px solid $active_dark;
|
7
|
+
}
|
8
|
+
}
|
9
|
+
|
10
|
+
[class^="pb_table"] {
|
11
|
+
&.table-sm,
|
12
|
+
&.table-md,
|
13
|
+
&.table-lg {
|
14
|
+
&.table-card {
|
15
|
+
tbody,
|
16
|
+
.pb_table_tbody {
|
17
|
+
tr,
|
18
|
+
.pb_table_tr {
|
19
|
+
&.collapsible_table_row {
|
20
|
+
td,
|
21
|
+
.pb_table_td {
|
22
|
+
border-bottom-color: transparent;
|
23
|
+
}
|
24
|
+
&:hover {
|
25
|
+
td,
|
26
|
+
.pb_table_td {
|
27
|
+
border-bottom-color: darken($border_light, 10%);
|
28
|
+
}
|
29
|
+
}
|
30
|
+
}
|
31
|
+
}
|
32
|
+
}
|
33
|
+
}
|
34
|
+
}
|
35
|
+
}
|
@@ -7,14 +7,21 @@ import {
|
|
7
7
|
buildHtmlProps,
|
8
8
|
} from "../../utilities/props";
|
9
9
|
import { globalProps } from "../../utilities/globalProps";
|
10
|
+
import Collapsible from "../../pb_collapsible/_collapsible";
|
11
|
+
import useCollapsible from "../../pb_collapsible/useCollapsible";
|
10
12
|
|
11
13
|
type TableRowPropTypes = {
|
12
14
|
aria?: { [key: string]: string };
|
13
15
|
children: React.ReactNode[] | React.ReactNode;
|
14
16
|
className: string;
|
17
|
+
collapsible?: boolean;
|
18
|
+
collapsibleContent?: React.ReactNode[] | React.ReactNode;
|
19
|
+
collapsibleSideHighlight?: boolean;
|
15
20
|
data?: { [key: string]: string };
|
21
|
+
dark?: boolean;
|
16
22
|
htmlOptions?: { [key: string]: string | number | boolean | (() => void) };
|
17
23
|
id?: string;
|
24
|
+
toggleCellId?: string;
|
18
25
|
sideHighlightColor: string;
|
19
26
|
tag?: "table" | "div";
|
20
27
|
};
|
@@ -23,10 +30,15 @@ const TableRow = (props: TableRowPropTypes): React.ReactElement => {
|
|
23
30
|
const {
|
24
31
|
aria = {},
|
25
32
|
children,
|
33
|
+
collapsible,
|
34
|
+
collapsibleContent,
|
35
|
+
collapsibleSideHighlight = true,
|
26
36
|
className,
|
27
37
|
data = {},
|
38
|
+
dark = false,
|
28
39
|
htmlOptions = {},
|
29
40
|
id,
|
41
|
+
toggleCellId,
|
30
42
|
sideHighlightColor = "none",
|
31
43
|
tag = "table",
|
32
44
|
} = props;
|
@@ -36,17 +48,110 @@ const TableRow = (props: TableRowPropTypes): React.ReactElement => {
|
|
36
48
|
const htmlProps = buildHtmlProps(htmlOptions);
|
37
49
|
const sideHighlightClass =
|
38
50
|
sideHighlightColor != "" ? `side_highlight_${sideHighlightColor}` : null;
|
51
|
+
|
52
|
+
const [isCollapsed, setIsCollapsed] = useCollapsible(true);
|
53
|
+
|
54
|
+
const collapsibleRow = collapsible && isCollapsed === true ? "collapsible_table_row" : null;
|
39
55
|
const classes = classnames(
|
40
56
|
buildCss("pb_table_row_kit", sideHighlightClass),
|
41
57
|
"pb_table_tr",
|
58
|
+
collapsibleRow,
|
42
59
|
globalProps(props),
|
43
60
|
className
|
44
61
|
);
|
45
62
|
const isTableTag = tag === "table";
|
46
63
|
|
64
|
+
// const [isCollapsed, setIsCollapsed] = useCollapsible(true);
|
65
|
+
|
66
|
+
const colSpan = React.Children.count(children);
|
67
|
+
|
68
|
+
const handleRowClick = (event: React.MouseEvent) => {
|
69
|
+
if (toggleCellId) {
|
70
|
+
const target = event.target as HTMLElement;
|
71
|
+
const clickedCell = target.closest(`#${toggleCellId}`);
|
72
|
+
const isIconClick =
|
73
|
+
target instanceof SVGElement &&
|
74
|
+
(target.matches("svg.pb_custom_icon") || target.closest("svg.pb_custom_icon"));
|
75
|
+
|
76
|
+
if (clickedCell || isIconClick) {
|
77
|
+
setIsCollapsed(!isCollapsed);
|
78
|
+
}
|
79
|
+
} else {
|
80
|
+
setIsCollapsed(!isCollapsed);
|
81
|
+
}
|
82
|
+
};
|
83
|
+
|
47
84
|
return (
|
48
85
|
<>
|
49
|
-
{
|
86
|
+
{collapsible ? (
|
87
|
+
isTableTag ? (
|
88
|
+
<>
|
89
|
+
<tr
|
90
|
+
{...ariaProps}
|
91
|
+
{...dataProps}
|
92
|
+
{...htmlProps}
|
93
|
+
className={classes}
|
94
|
+
id={id}
|
95
|
+
onClick={(e)=>handleRowClick(e)}
|
96
|
+
style={{ cursor: toggleCellId ? "default" : "pointer" }}
|
97
|
+
>
|
98
|
+
{children}
|
99
|
+
</tr>
|
100
|
+
<tr>
|
101
|
+
<Collapsible
|
102
|
+
collapsed={isCollapsed}
|
103
|
+
dark={dark}
|
104
|
+
htmlOptions={{ colSpan: colSpan }}
|
105
|
+
padding="none"
|
106
|
+
tag="td"
|
107
|
+
>
|
108
|
+
<tr/>
|
109
|
+
<Collapsible.Content
|
110
|
+
className={collapsibleSideHighlight ? `table_collapsible_side_highlight` : ''}
|
111
|
+
dark={dark}
|
112
|
+
margin="none"
|
113
|
+
padding="none"
|
114
|
+
>
|
115
|
+
{collapsibleContent}
|
116
|
+
</Collapsible.Content>
|
117
|
+
</Collapsible>
|
118
|
+
</tr>
|
119
|
+
</>
|
120
|
+
) : (
|
121
|
+
<>
|
122
|
+
<div
|
123
|
+
{...ariaProps}
|
124
|
+
{...dataProps}
|
125
|
+
{...htmlProps}
|
126
|
+
className={classes}
|
127
|
+
id={id}
|
128
|
+
onClick={handleRowClick}
|
129
|
+
style={{ cursor: "pointer" }}
|
130
|
+
>
|
131
|
+
{children}
|
132
|
+
</div>
|
133
|
+
<tr>
|
134
|
+
<Collapsible
|
135
|
+
collapsed={isCollapsed}
|
136
|
+
dark={dark}
|
137
|
+
htmlOptions={{ colSpan: colSpan }}
|
138
|
+
padding="none"
|
139
|
+
tag="td"
|
140
|
+
>
|
141
|
+
<tr/>
|
142
|
+
<Collapsible.Content
|
143
|
+
className={collapsibleSideHighlight ? `table_collapsible_side_highlight` : ''}
|
144
|
+
dark={dark}
|
145
|
+
margin="none"
|
146
|
+
padding="none"
|
147
|
+
>
|
148
|
+
{collapsibleContent}
|
149
|
+
</Collapsible.Content>
|
150
|
+
</Collapsible>
|
151
|
+
</tr>
|
152
|
+
</>
|
153
|
+
)
|
154
|
+
) : isTableTag ? (
|
50
155
|
<tr
|
51
156
|
{...ariaProps}
|
52
157
|
{...dataProps}
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import React, { forwardRef } from 'react'
|
1
|
+
import React, { forwardRef, ChangeEvent } from 'react'
|
2
2
|
import classnames from 'classnames'
|
3
3
|
|
4
4
|
import { globalProps, GlobalProps, domSafeProps } from '../utilities/globalProps'
|
@@ -10,6 +10,8 @@ import Caption from '../pb_caption/_caption'
|
|
10
10
|
import Body from '../pb_body/_body'
|
11
11
|
import Icon from '../pb_icon/_icon'
|
12
12
|
|
13
|
+
import { INPUTMASKS } from './inputMask'
|
14
|
+
|
13
15
|
type TextInputProps = {
|
14
16
|
aria?: { [key: string]: string },
|
15
17
|
className?: string,
|
@@ -22,6 +24,7 @@ type TextInputProps = {
|
|
22
24
|
inline?: boolean,
|
23
25
|
name: string,
|
24
26
|
label: string,
|
27
|
+
mask?: 'currency' | 'zipCode' | 'postalCode' | 'ssn',
|
25
28
|
onChange: (e: React.FormEvent<HTMLInputElement>) => void,
|
26
29
|
placeholder: string,
|
27
30
|
required?: boolean,
|
@@ -47,6 +50,7 @@ const TextInput = (props: TextInputProps, ref: React.LegacyRef<HTMLInputElement>
|
|
47
50
|
htmlOptions = {},
|
48
51
|
id,
|
49
52
|
inline = false,
|
53
|
+
mask = null,
|
50
54
|
name,
|
51
55
|
label,
|
52
56
|
onChange = () => { void 0 },
|
@@ -90,6 +94,33 @@ const TextInput = (props: TextInputProps, ref: React.LegacyRef<HTMLInputElement>
|
|
90
94
|
/>
|
91
95
|
)
|
92
96
|
|
97
|
+
const isMaskedInput = mask && mask in INPUTMASKS
|
98
|
+
|
99
|
+
const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
|
100
|
+
if (isMaskedInput) {
|
101
|
+
const inputValue = e.target.value
|
102
|
+
|
103
|
+
let cursorPosition = e.target.selectionStart;
|
104
|
+
const isAtEnd = cursorPosition === inputValue.length;
|
105
|
+
|
106
|
+
const formattedValue = INPUTMASKS[mask].format(inputValue)
|
107
|
+
e.target.value = formattedValue
|
108
|
+
|
109
|
+
// Keep cursor position
|
110
|
+
if (!isAtEnd) {
|
111
|
+
// Account for extra characters (e.g., commas added/removed in currency)
|
112
|
+
if (formattedValue.length - inputValue.length === 1) {
|
113
|
+
cursorPosition = cursorPosition + 1
|
114
|
+
} else if (mask === "currency" && formattedValue.length - inputValue.length === -1) {
|
115
|
+
cursorPosition = cursorPosition - 1
|
116
|
+
}
|
117
|
+
e.target.selectionStart = e.target.selectionEnd = cursorPosition
|
118
|
+
}
|
119
|
+
}
|
120
|
+
|
121
|
+
onChange(e)
|
122
|
+
}
|
123
|
+
|
93
124
|
const childInput = children ? children.type === "input" : undefined
|
94
125
|
|
95
126
|
const textInput = (
|
@@ -101,8 +132,9 @@ const TextInput = (props: TextInputProps, ref: React.LegacyRef<HTMLInputElement>
|
|
101
132
|
id={id}
|
102
133
|
key={id}
|
103
134
|
name={name}
|
104
|
-
onChange={onChange}
|
105
|
-
|
135
|
+
onChange={isMaskedInput ? handleChange : onChange}
|
136
|
+
pattern={isMaskedInput ? INPUTMASKS[mask]?.pattern : undefined}
|
137
|
+
placeholder={placeholder || (isMaskedInput ? INPUTMASKS[mask]?.placeholder : undefined)}
|
106
138
|
ref={ref}
|
107
139
|
required={required}
|
108
140
|
type={type}
|
@@ -0,0 +1,88 @@
|
|
1
|
+
import React, { useState } from 'react'
|
2
|
+
|
3
|
+
import Caption from '../../pb_caption/_caption'
|
4
|
+
import TextInput from '../../pb_text_input/_text_input'
|
5
|
+
import Title from '../../pb_title/_title'
|
6
|
+
|
7
|
+
const TextInputMask = (props) => {
|
8
|
+
const [ssn, setSSN] = useState('')
|
9
|
+
const handleOnChangeSSN = ({ target }) => {
|
10
|
+
setSSN(target.value)
|
11
|
+
}
|
12
|
+
const ref = React.createRef()
|
13
|
+
|
14
|
+
const [formFields, setFormFields] = useState({
|
15
|
+
currency: '',
|
16
|
+
zipCode: '',
|
17
|
+
postalCode: '',
|
18
|
+
ssn: '',
|
19
|
+
})
|
20
|
+
|
21
|
+
const handleOnChangeFormField = ({ target }) => {
|
22
|
+
const { name, value } = target
|
23
|
+
setFormFields({ ...formFields, [name]: value })
|
24
|
+
}
|
25
|
+
|
26
|
+
return (
|
27
|
+
<div>
|
28
|
+
<TextInput
|
29
|
+
label="Currency"
|
30
|
+
mask="currency"
|
31
|
+
name="currency"
|
32
|
+
onChange={handleOnChangeFormField}
|
33
|
+
value={formFields.currency}
|
34
|
+
{...props}
|
35
|
+
/>
|
36
|
+
<TextInput
|
37
|
+
label="Zip Code"
|
38
|
+
mask="zipCode"
|
39
|
+
name="zipCode"
|
40
|
+
onChange={handleOnChangeFormField}
|
41
|
+
value={formFields.zipCode}
|
42
|
+
{...props}
|
43
|
+
/>
|
44
|
+
<TextInput
|
45
|
+
label="Postal Code"
|
46
|
+
mask="postalCode"
|
47
|
+
name="postalCode"
|
48
|
+
onChange={handleOnChangeFormField}
|
49
|
+
value={formFields.postalCode}
|
50
|
+
{...props}
|
51
|
+
/>
|
52
|
+
<TextInput
|
53
|
+
label="SSN"
|
54
|
+
mask="ssn"
|
55
|
+
name="ssn"
|
56
|
+
onChange={handleOnChangeFormField}
|
57
|
+
value={formFields.ssn}
|
58
|
+
{...props}
|
59
|
+
/>
|
60
|
+
|
61
|
+
<br />
|
62
|
+
<br />
|
63
|
+
|
64
|
+
<Title>{'Event Handler Props'}</Title>
|
65
|
+
|
66
|
+
<br />
|
67
|
+
<Caption>{'onChange'}</Caption>
|
68
|
+
|
69
|
+
<br />
|
70
|
+
|
71
|
+
<TextInput
|
72
|
+
label="SSN"
|
73
|
+
mask="ssn"
|
74
|
+
onChange={handleOnChangeSSN}
|
75
|
+
placeholder="Enter SSN"
|
76
|
+
ref={ref}
|
77
|
+
value={ssn}
|
78
|
+
{...props}
|
79
|
+
/>
|
80
|
+
|
81
|
+
{ssn !== '' && (
|
82
|
+
<React.Fragment>{`SSN is: ${ssn}`}</React.Fragment>
|
83
|
+
)}
|
84
|
+
</div>
|
85
|
+
)
|
86
|
+
}
|
87
|
+
|
88
|
+
export default TextInputMask
|