playbook_ui 14.5.0.pre.alpha.PBNTR374multilevelselectPOC3946 → 14.5.0.pre.alpha.PBNTR606multilevelselectreset4035
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/pb_form_pill/_form_pill.tsx +9 -1
- data/app/pb_kits/playbook/pb_form_pill/docs/_form_pill_truncated_text.html.erb +19 -0
- data/app/pb_kits/playbook/pb_form_pill/docs/_form_pill_truncated_text.jsx +27 -0
- data/app/pb_kits/playbook/pb_form_pill/docs/_form_pill_truncated_text.md +1 -0
- data/app/pb_kits/playbook/pb_form_pill/docs/example.yml +2 -0
- data/app/pb_kits/playbook/pb_form_pill/docs/index.js +1 -0
- data/app/pb_kits/playbook/pb_multi_level_select/_multi_level_select.tsx +19 -2
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_reset.html.erb +93 -0
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_with_children.jsx +5 -7
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_with_children.md +1 -0
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_with_children_with_radios.jsx +5 -7
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_with_children_with_radios.md +1 -0
- data/app/pb_kits/playbook/pb_multi_level_select/docs/example.yml +1 -0
- data/app/pb_kits/playbook/pb_typeahead/_typeahead.tsx +4 -1
- data/app/pb_kits/playbook/pb_typeahead/components/MultiValue.tsx +3 -1
- data/app/pb_kits/playbook/pb_typeahead/typeahead.rb +3 -1
- data/dist/chunks/{_typeahead-DMIBeCYd.js → _typeahead-C9g4qCcE.js} +1 -1
- data/dist/chunks/{_weekday_stacked-CviGlw2m.js → _weekday_stacked-Div3Fpd3.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/lib/playbook/version.rb +1 -1
- metadata +10 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0ac1d308be087420aa261bc98d4426758ede289c17ce212986640dfe2a91ead9
|
4
|
+
data.tar.gz: 69012507d1a2108c08b12bc1033f6b80256ed4d760e75942ecfb63935192ba14
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 11e1d28af538f892e85fe0712d407bd952974007fe9694226517dd483fdc262eb09df2ee1dd44b47a7df396806f660102ed211dfbed50da82852aee526c3c0fe
|
7
|
+
data.tar.gz: 990e9168c014f6e06108e5fec5c6efe98349282fd80440b74696b784c82b2fd49c05330e93c7ab8b4e2377bb7d148b42c386aa157fddbeac43712d61b1250ce8
|
@@ -47,9 +47,13 @@ const FormPill = (props: FormPillProps): React.ReactElement => {
|
|
47
47
|
|
48
48
|
const iconClass = icon ? "_icon" : ""
|
49
49
|
const closeIconSize = size === "small" ? "xs" : "sm"
|
50
|
+
|
51
|
+
const filteredProps: FormPillProps = {...props}
|
52
|
+
delete filteredProps.truncate
|
53
|
+
|
50
54
|
const css = classnames(
|
51
55
|
`pb_form_pill_kit_${color}${iconClass}`,
|
52
|
-
globalProps(
|
56
|
+
globalProps(filteredProps),
|
53
57
|
className,
|
54
58
|
size === 'small' ? 'small' : null,
|
55
59
|
textTransform,
|
@@ -77,6 +81,7 @@ const FormPill = (props: FormPillProps): React.ReactElement => {
|
|
77
81
|
className="pb_form_pill_text"
|
78
82
|
size={4}
|
79
83
|
text={name}
|
84
|
+
truncate={props.truncate}
|
80
85
|
/>
|
81
86
|
</>
|
82
87
|
)}
|
@@ -92,6 +97,7 @@ const FormPill = (props: FormPillProps): React.ReactElement => {
|
|
92
97
|
className="pb_form_pill_text"
|
93
98
|
size={4}
|
94
99
|
text={name}
|
100
|
+
truncate={props.truncate}
|
95
101
|
/>
|
96
102
|
<Icon
|
97
103
|
className="pb_form_pill_icon"
|
@@ -111,6 +117,7 @@ const FormPill = (props: FormPillProps): React.ReactElement => {
|
|
111
117
|
className="pb_form_pill_tag"
|
112
118
|
size={4}
|
113
119
|
text={text}
|
120
|
+
truncate={props.truncate}
|
114
121
|
/>
|
115
122
|
</>
|
116
123
|
)}
|
@@ -119,6 +126,7 @@ const FormPill = (props: FormPillProps): React.ReactElement => {
|
|
119
126
|
className="pb_form_pill_tag"
|
120
127
|
size={4}
|
121
128
|
text={text}
|
129
|
+
truncate={props.truncate}
|
122
130
|
/>
|
123
131
|
)}
|
124
132
|
<div
|
@@ -0,0 +1,19 @@
|
|
1
|
+
<%
|
2
|
+
names = [
|
3
|
+
{ label: 'Alexander Nathaniel Montgomery', value: 'Alexander Nathaniel Montgomery' },
|
4
|
+
{ label: 'Isabella Anastasia Wellington', value: 'Isabella Anastasia Wellington' },
|
5
|
+
{ label: 'Christopher Maximilian Harrington', value: 'Christopher Maximilian Harrington' },
|
6
|
+
{ label: 'Elizabeth Seraphina Kensington', value: 'Elizabeth Seraphina Kensington' },
|
7
|
+
{ label: 'Theodore Jonathan Abernathy', value: 'Theodore Jonathan Abernathy' },
|
8
|
+
]
|
9
|
+
%>
|
10
|
+
|
11
|
+
<%= pb_rails("typeahead", props: {
|
12
|
+
html_options: { style: { maxWidth: "240px" }},
|
13
|
+
id: "typeahead-form-pill",
|
14
|
+
is_multi: true,
|
15
|
+
options: names,
|
16
|
+
label: "Names",
|
17
|
+
pills: true,
|
18
|
+
truncate: 1,
|
19
|
+
}) %>
|
@@ -0,0 +1,27 @@
|
|
1
|
+
import React from 'react'
|
2
|
+
import Typeahead from '../../pb_typeahead/_typeahead'
|
3
|
+
|
4
|
+
const names = [
|
5
|
+
{ label: 'Alexander Nathaniel Montgomery', value: 'Alexander Nathaniel Montgomery' },
|
6
|
+
{ label: 'Isabella Anastasia Wellington', value: 'Isabella Anastasia Wellington' },
|
7
|
+
{ label: 'Christopher Maximilian Harrington', value: 'Christopher Maximilian Harrington' },
|
8
|
+
{ label: 'Elizabeth Seraphina Kensington', value: 'Elizabeth Seraphina Kensington' },
|
9
|
+
{ label: 'Theodore Jonathan Abernathy', value: 'Theodore Jonathan Abernathy' },
|
10
|
+
]
|
11
|
+
|
12
|
+
const FormPillTruncatedText = (props) => {
|
13
|
+
return (
|
14
|
+
<>
|
15
|
+
<Typeahead
|
16
|
+
htmlOptions={{ style: { maxWidth: "240px" }}}
|
17
|
+
isMulti
|
18
|
+
label="Names"
|
19
|
+
options={names}
|
20
|
+
truncate={1}
|
21
|
+
{...props}
|
22
|
+
/>
|
23
|
+
</>
|
24
|
+
)
|
25
|
+
}
|
26
|
+
|
27
|
+
export default FormPillTruncatedText
|
@@ -0,0 +1 @@
|
|
1
|
+
For pills with longer text, the `truncate` global prop can be used to truncate the label within each Form Pill. See [here](https://playbook.powerapp.cloud/visual_guidelines/truncate) for more information on the truncate global prop.
|
@@ -3,6 +3,7 @@ examples:
|
|
3
3
|
rails:
|
4
4
|
- form_pill_user: Form Pill User
|
5
5
|
- form_pill_size: Form Pill Size
|
6
|
+
- form_pill_truncated_text: Truncated Text
|
6
7
|
- form_pill_tag: Form Pill Tag
|
7
8
|
- form_pill_example: Example
|
8
9
|
- form_pill_icon: Form Pill Icon
|
@@ -11,6 +12,7 @@ examples:
|
|
11
12
|
react:
|
12
13
|
- form_pill_user: Form Pill User
|
13
14
|
- form_pill_size: Form Pill Size
|
15
|
+
- form_pill_truncated_text: Truncated Text
|
14
16
|
- form_pill_tag: Form Pill Tag
|
15
17
|
- form_pill_example: Example
|
16
18
|
- form_pill_icon: Form Pill Icon
|
@@ -4,3 +4,4 @@ export { default as FormPillTag } from './_form_pill_tag.jsx'
|
|
4
4
|
export { default as FormPillExample } from './_form_pill_example.jsx'
|
5
5
|
export { default as FormPillIcon } from './_form_pill_icon.jsx'
|
6
6
|
export { default as FormPillColors } from './_form_pill_colors.jsx'
|
7
|
+
export { default as FormPillTruncatedText } from './_form_pill_truncated_text.jsx'
|
@@ -202,6 +202,23 @@ const MultiLevelSelect = (props: MultiLevelSelectProps) => {
|
|
202
202
|
};
|
203
203
|
}, []);
|
204
204
|
|
205
|
+
useEffect(() => {
|
206
|
+
if (id) {
|
207
|
+
// Attach the clear function to the window, scoped by the id
|
208
|
+
(window as any)[`clearMultiLevelSelect_${id}`] = () => {
|
209
|
+
const resetData = modifyRecursive(formattedData, false);
|
210
|
+
setFormattedData(resetData);
|
211
|
+
setReturnedArray([]);
|
212
|
+
setDefaultReturn([]);
|
213
|
+
setSingleSelectedItem({ id: [], value: "", item: [] });
|
214
|
+
onSelect([]);
|
215
|
+
};
|
216
|
+
return () => {
|
217
|
+
delete (window as any)[`clearMultiLevelSelect_${id}`];
|
218
|
+
};
|
219
|
+
}
|
220
|
+
}, [formattedData, id, onSelect]);
|
221
|
+
|
205
222
|
// Iterate over tree, find item and set checked or unchecked
|
206
223
|
const modifyValue = (
|
207
224
|
id: string,
|
@@ -367,7 +384,7 @@ const MultiLevelSelect = (props: MultiLevelSelectProps) => {
|
|
367
384
|
// Rendering formattedData to UI based on typeahead
|
368
385
|
const renderNestedOptions = (items: { [key: string]: string; }[] | any ) => {
|
369
386
|
const hasOptionsChild = React.Children.toArray(props.children).some(
|
370
|
-
child => child.type === MultiLevelSelect.Options
|
387
|
+
(child: any) => child.type === MultiLevelSelect.Options
|
371
388
|
);
|
372
389
|
|
373
390
|
if (hasOptionsChild) {
|
@@ -378,7 +395,7 @@ const MultiLevelSelect = (props: MultiLevelSelectProps) => {
|
|
378
395
|
return null;
|
379
396
|
});
|
380
397
|
} else {
|
381
|
-
// If
|
398
|
+
// If no children, use the default rendering
|
382
399
|
return (
|
383
400
|
<MultiLevelSelectOptions items={items} />
|
384
401
|
);
|
@@ -0,0 +1,93 @@
|
|
1
|
+
<% treeData = [{
|
2
|
+
label: "Power Home Remodeling",
|
3
|
+
value: "Power Home Remodeling",
|
4
|
+
id: "100",
|
5
|
+
expanded: true,
|
6
|
+
children: [
|
7
|
+
{
|
8
|
+
label: "People",
|
9
|
+
value: "People",
|
10
|
+
id: "101",
|
11
|
+
expanded: true,
|
12
|
+
children: [
|
13
|
+
{
|
14
|
+
label: "Talent Acquisition",
|
15
|
+
value: "Talent Acquisition",
|
16
|
+
id: "102",
|
17
|
+
},
|
18
|
+
{
|
19
|
+
label: "Business Affairs",
|
20
|
+
value: "Business Affairs",
|
21
|
+
id: "103",
|
22
|
+
children: [
|
23
|
+
{
|
24
|
+
label: "Initiatives",
|
25
|
+
value: "Initiatives",
|
26
|
+
id: "104",
|
27
|
+
},
|
28
|
+
{
|
29
|
+
label: "Learning & Development",
|
30
|
+
value: "Learning & Development",
|
31
|
+
id: "105",
|
32
|
+
},
|
33
|
+
],
|
34
|
+
},
|
35
|
+
{
|
36
|
+
label: "People Experience",
|
37
|
+
value: "People Experience",
|
38
|
+
id: "106",
|
39
|
+
},
|
40
|
+
],
|
41
|
+
},
|
42
|
+
{
|
43
|
+
label: "Contact Center",
|
44
|
+
value: "Contact Center",
|
45
|
+
id: "107",
|
46
|
+
children: [
|
47
|
+
{
|
48
|
+
label: "Appointment Management",
|
49
|
+
value: "Appointment Management",
|
50
|
+
id: "108",
|
51
|
+
},
|
52
|
+
{
|
53
|
+
label: "Customer Service",
|
54
|
+
value: "Customer Service",
|
55
|
+
id: "109",
|
56
|
+
},
|
57
|
+
{
|
58
|
+
label: "Energy",
|
59
|
+
value: "Energy",
|
60
|
+
id: "110",
|
61
|
+
},
|
62
|
+
],
|
63
|
+
},
|
64
|
+
],
|
65
|
+
}] %>
|
66
|
+
|
67
|
+
<%= pb_rails("multi_level_select", props: {
|
68
|
+
id: "multi-level-select-reset-example",
|
69
|
+
name: "my_array",
|
70
|
+
tree_data: treeData,
|
71
|
+
return_all_selected: true
|
72
|
+
}) %>
|
73
|
+
|
74
|
+
<%= pb_rails("button", props: { text: "Reset", margin_top: "lg", id:"multilevelselect-reset-button" }) %>
|
75
|
+
|
76
|
+
|
77
|
+
<script>
|
78
|
+
window.addEventListener('DOMContentLoaded', () => {
|
79
|
+
const exampleResetButton = document.querySelector("#multilevelselect-reset-button");
|
80
|
+
|
81
|
+
exampleResetButton.addEventListener("click", () => {
|
82
|
+
clearMultiLevelSelectById('multi-level-select-reset-example');
|
83
|
+
});
|
84
|
+
function clearMultiLevelSelectById(id) {
|
85
|
+
const clearFunction = window[`clearMultiLevelSelect_${id}`];
|
86
|
+
if (clearFunction) {
|
87
|
+
clearFunction();
|
88
|
+
} else {
|
89
|
+
console.warn(`No clear function found for MultiLevelSelect with id: ${id}`);
|
90
|
+
}
|
91
|
+
}
|
92
|
+
})
|
93
|
+
</script>
|
@@ -90,13 +90,11 @@ const MultiLevelSelectWithChildren = (props) => {
|
|
90
90
|
>
|
91
91
|
<MultiLevelSelect.Options>
|
92
92
|
{(item) => (
|
93
|
-
<
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
/>
|
99
|
-
</div>
|
93
|
+
<Badge
|
94
|
+
marginLeft="sm"
|
95
|
+
text={item.status}
|
96
|
+
variant={item.status === "active" ? "success" : "warning"}
|
97
|
+
/>
|
100
98
|
)}
|
101
99
|
</MultiLevelSelect.Options>
|
102
100
|
</MultiLevelSelect>
|
@@ -0,0 +1 @@
|
|
1
|
+
The MultiLevelSelect also provides a subcomponent structure which can be used to render children to the right of the Checkboxes and their labels. As seen in the code snippet below, these children have access to the current item being iterated over which can be used for conditional rendering.
|
@@ -91,13 +91,11 @@ const MultiLevelSelectWithChildrenWithRadios = (props) => {
|
|
91
91
|
>
|
92
92
|
<MultiLevelSelect.Options>
|
93
93
|
{(item) => (
|
94
|
-
<
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
/>
|
100
|
-
</div>
|
94
|
+
<Badge
|
95
|
+
marginLeft="sm"
|
96
|
+
text={item.status}
|
97
|
+
variant={item.status === "active" ? "success" : "warning"}
|
98
|
+
/>
|
101
99
|
)}
|
102
100
|
</MultiLevelSelect.Options>
|
103
101
|
</MultiLevelSelect>
|
@@ -0,0 +1 @@
|
|
1
|
+
The MultiLevelSelect subcomponent structure is also available in the 'Single Select' variant. In this variant, the children will be rendered to the right of the Radios and their labels.
|
@@ -136,12 +136,15 @@ const Typeahead = ({
|
|
136
136
|
}
|
137
137
|
}
|
138
138
|
|
139
|
+
const filteredProps: TypeaheadProps = {...props}
|
140
|
+
delete filteredProps.truncate
|
141
|
+
|
139
142
|
const dataProps = buildDataProps(data)
|
140
143
|
const htmlProps = buildHtmlProps(htmlOptions)
|
141
144
|
const classes = classnames(
|
142
145
|
'pb_typeahead_kit react-select',
|
143
146
|
`mb_${marginBottom}`,
|
144
|
-
globalProps(
|
147
|
+
globalProps(filteredProps),
|
145
148
|
className
|
146
149
|
)
|
147
150
|
|
@@ -16,7 +16,7 @@ type Props = {
|
|
16
16
|
const MultiValue = (props: Props) => {
|
17
17
|
const { removeProps } = props
|
18
18
|
const { imageUrl, label } = props.data
|
19
|
-
const { dark, multiKit, pillColor } = props.selectProps
|
19
|
+
const { dark, multiKit, pillColor, truncate } = props.selectProps
|
20
20
|
|
21
21
|
const formPillProps = {
|
22
22
|
marginRight: 'xs',
|
@@ -51,6 +51,7 @@ const MultiValue = (props: Props) => {
|
|
51
51
|
name={label}
|
52
52
|
size={multiKit === 'smallPill' ? 'small' : ''}
|
53
53
|
text=''
|
54
|
+
truncate={truncate}
|
54
55
|
{...props}
|
55
56
|
/>
|
56
57
|
}
|
@@ -64,6 +65,7 @@ const MultiValue = (props: Props) => {
|
|
64
65
|
name=''
|
65
66
|
size={multiKit === 'smallPill' ? 'small' : ''}
|
66
67
|
text={label}
|
68
|
+
truncate={truncate}
|
67
69
|
{...props}
|
68
70
|
/>
|
69
71
|
}
|
@@ -65,10 +65,10 @@ module Playbook
|
|
65
65
|
def typeahead_react_options
|
66
66
|
base_options = {
|
67
67
|
className: classname,
|
68
|
-
pillColor: pill_color,
|
69
68
|
dark: dark,
|
70
69
|
defaultValue: default_options,
|
71
70
|
error: error,
|
71
|
+
htmlOptions: html_options,
|
72
72
|
id: id,
|
73
73
|
inline: inline,
|
74
74
|
isMulti: is_multi,
|
@@ -77,8 +77,10 @@ module Playbook
|
|
77
77
|
multiKit: multi_kit,
|
78
78
|
name: name,
|
79
79
|
options: options,
|
80
|
+
pillColor: pill_color,
|
80
81
|
placeholder: placeholder,
|
81
82
|
plusIcon: plus_icon,
|
83
|
+
truncate: truncate,
|
82
84
|
}
|
83
85
|
|
84
86
|
base_options[:getOptionLabel] = get_option_label if get_option_label.present?
|