playbook_ui 14.15.0.pre.alpha.play1910emptystatekitreactbeta6579 → 14.15.0.pre.alpha.play1910emptystatekitreactbeta6685

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.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.scss +7 -0
  3. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_inline_editing.jsx +102 -0
  4. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_inline_editing.md +4 -0
  5. data/app/pb_kits/playbook/pb_advanced_table/docs/example.yml +2 -1
  6. data/app/pb_kits/playbook/pb_advanced_table/docs/index.js +2 -1
  7. data/app/pb_kits/playbook/pb_empty_state/_empty_state.tsx +17 -3
  8. data/app/pb_kits/playbook/pb_empty_state/docs/_empty_state_alignment.jsx +3 -3
  9. data/app/pb_kits/playbook/pb_empty_state/docs/_empty_state_orientation.jsx +1 -1
  10. data/app/pb_kits/playbook/pb_empty_state/docs/_empty_state_size.jsx +2 -2
  11. data/app/pb_kits/playbook/pb_empty_state/docs/default_image/computer_fly_no_branding.svg +21 -0
  12. data/app/pb_kits/playbook/pb_empty_state/docs/default_image/utils.tsx +122 -0
  13. data/app/pb_kits/playbook/pb_form/docs/_form_form_with.html.erb +1 -1
  14. data/app/pb_kits/playbook/pb_form/docs/_form_form_with_validate.html.erb +1 -1
  15. data/app/pb_kits/playbook/pb_icon_button/_icon_button.tsx +1 -1
  16. data/app/pb_kits/playbook/pb_icon_button/icon_button.html.erb +1 -1
  17. data/app/pb_kits/playbook/pb_multi_level_select/_multi_level_select.tsx +32 -5
  18. data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_react_hook.jsx +91 -0
  19. data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_react_hook.md +1 -0
  20. data/app/pb_kits/playbook/pb_multi_level_select/docs/example.yml +1 -0
  21. data/app/pb_kits/playbook/pb_multi_level_select/docs/index.js +1 -0
  22. data/app/pb_kits/playbook/pb_multi_level_select/multi_level_select.rb +1 -1
  23. data/app/pb_kits/playbook/pb_phone_number_input/_phone_number_input.tsx +6 -0
  24. data/app/pb_kits/playbook/pb_phone_number_input/docs/_phone_number_input_default.html.erb +1 -1
  25. data/app/pb_kits/playbook/pb_phone_number_input/docs/_phone_number_input_hidden_inputs.html.erb +5 -0
  26. data/app/pb_kits/playbook/pb_phone_number_input/docs/_phone_number_input_hidden_inputs.md +1 -0
  27. data/app/pb_kits/playbook/pb_phone_number_input/docs/example.yml +3 -1
  28. data/app/pb_kits/playbook/pb_phone_number_input/phone_number_input.rb +3 -0
  29. data/app/pb_kits/playbook/pb_popover/_popover.tsx +1 -1
  30. data/app/pb_kits/playbook/pb_popover/popover.test.js +1 -1
  31. data/app/pb_kits/playbook/pb_text_input/inputMask.ts +2 -3
  32. data/app/pb_kits/playbook/pb_tooltip/docs/_tooltip_icon_rails.html.erb +22 -0
  33. data/app/pb_kits/playbook/pb_tooltip/docs/example.yml +1 -0
  34. data/app/pb_kits/playbook/pb_typeahead/_typeahead.tsx +16 -4
  35. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_react_hook.jsx +66 -0
  36. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_react_hook.md +1 -0
  37. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_with_pills_async_custom_options.jsx +1 -1
  38. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_with_pills_async_users.jsx +1 -1
  39. data/app/pb_kits/playbook/pb_typeahead/docs/example.yml +1 -0
  40. data/app/pb_kits/playbook/pb_typeahead/docs/index.js +1 -0
  41. data/dist/chunks/_typeahead-Z1NtlQ7Y.js +36 -0
  42. data/dist/chunks/_weekday_stacked-Bh2hQ0JB.js +45 -0
  43. data/dist/chunks/vendor.js +1 -1
  44. data/dist/menu.yml +1 -1
  45. data/dist/playbook-doc.js +1 -1
  46. data/dist/playbook-rails-react-bindings.js +1 -1
  47. data/dist/playbook-rails.js +1 -1
  48. data/dist/playbook.css +1 -1
  49. data/lib/playbook/version.rb +1 -1
  50. metadata +15 -5
  51. data/app/pb_kits/playbook/pb_tooltip/docs/_tooltip_icon.erb +0 -10
  52. data/dist/chunks/_typeahead-D2Wtk1Vx.js +0 -36
  53. data/dist/chunks/_weekday_stacked-toeDpRDd.js +0 -45
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a4b6fab9ece5fae4518e897b8210410b09d0e556020f43189ba301003be177e1
4
- data.tar.gz: e0edb633f206fa6120fc1ffec4abf63481818afef913b8cf1cbfb9200e8ed4ff
3
+ metadata.gz: b5d72dcd60056b7f11f21d9d9df5773e495607966aacda253d3528e5de2472dd
4
+ data.tar.gz: fa73995286cadd1d924c88ff689de889f9e999d675ef968b540ea844cb5ef318
5
5
  SHA512:
6
- metadata.gz: 8c868d18999ce1bdff2d2bad36eebf0fe83debdd6527e0fbe8dccfb0cc2d2d2d8573c78f47a8cf3bf3f2c216f20f3e7bfaa2e4ffd4ef1a931b2a28392b216843
7
- data.tar.gz: a4bf1483d2e93163ca1e6b30088a6783696dee5d39f0f05075c4db4f48ca2ccaa5d53cd6a8afb7da3941b2c50dc64806e13e167839ee2065d70ea9053076d9db
6
+ metadata.gz: ee16de9591adb4f1ffca2153698188a125c122c6a1a83b8f69101c724ca32cda3f8eb193995345f9f3957f474a616f515e94efaca631d767fc88ab480c879d11
7
+ data.tar.gz: e9c9fe9eb4b2ddedfd99d61b3006e6e7b899134aa3492fc9ce7e0c606d58a88628d542fc8964cef94b484aa55d24c9954805ca5ec98f0f192f8b0ea0e41bc45a
@@ -161,6 +161,13 @@
161
161
  }
162
162
  }
163
163
  }
164
+ td {
165
+ [class^=pb_text_input_kit] .text_input_wrapper input {
166
+ padding: 0 $space_xxs;
167
+ font-size: 14px;
168
+ text-align: right;
169
+ }
170
+ }
164
171
  }
165
172
 
166
173
  .table-header-cells-active:first-child {
@@ -0,0 +1,102 @@
1
+ import React, { useState } from "react";
2
+ import { AdvancedTable, TextInput, Body } from "playbook-ui";
3
+ import MOCK_DATA from "./advanced_table_mock_data.json";
4
+
5
+ const AdvancedTableInlineEditing = (props) => {
6
+ const [editedValues, setEditedValues] = useState({});
7
+
8
+ const EditableCell = ({ rowId, originalValue, onSave }) => {
9
+ const [localValue, setLocalValue] = useState(originalValue);
10
+
11
+ const handleChange = (e) => setLocalValue(e.target.value);
12
+
13
+ const handleBlur = () => {
14
+ originalValue !== localValue && onSave(rowId, localValue);
15
+ };
16
+
17
+ return (
18
+ <TextInput inline
19
+ marginBottom="none"
20
+ {...props}
21
+ >
22
+ <input
23
+ onBlur={handleBlur}
24
+ onChange={handleChange}
25
+ onKeyDown={(e) => e.key === 'Enter' && handleBlur()}
26
+ value={localValue}
27
+ />
28
+ </TextInput>
29
+ );
30
+ };
31
+
32
+ const columnDefinitions = [
33
+ {
34
+ accessor: "year",
35
+ label: "Year",
36
+ cellAccessors: ["quarter", "month", "day"],
37
+ },
38
+ {
39
+ accessor: "newEnrollments",
40
+ label: "New Enrollments",
41
+ },
42
+ {
43
+ accessor: "scheduledMeetings",
44
+ label: "Scheduled Meetings",
45
+ editable: true,
46
+ customRenderer: (row) => {
47
+ return (
48
+ <EditableCell
49
+ onSave={(id, val) => {
50
+ setEditedValues((prev) => ({ ...prev, [id]: val }));
51
+ }}
52
+ originalValue={
53
+ editedValues[row.id] ?? row.original.scheduledMeetings
54
+ }
55
+ rowId={row.id}
56
+ />
57
+ );
58
+ },
59
+ },
60
+ {
61
+ accessor: "attendanceRate",
62
+ label: "Attendance Rate",
63
+ },
64
+ {
65
+ accessor: "completedClasses",
66
+ label: "Completed Classes",
67
+ },
68
+ {
69
+ accessor: "classCompletionRate",
70
+ label: "Class Completion Rate",
71
+ },
72
+ {
73
+ accessor: "graduatedStudents",
74
+ label: "Graduated Students",
75
+ },
76
+ ];
77
+
78
+ return (
79
+ <div className="App">
80
+ <AdvancedTable
81
+ columnDefinitions={columnDefinitions}
82
+ tableData={MOCK_DATA}
83
+ {...props}
84
+ />
85
+ {
86
+ editedValues && Object.keys(editedValues).length > 0 && (
87
+ <>
88
+ <Body
89
+ marginTop="md"
90
+ {...props}
91
+ >
92
+ Edited Values by Row Id:
93
+ </Body>
94
+ <pre style={{color: 'white'}}>{JSON.stringify(editedValues, null, 2)}</pre>
95
+ </>
96
+ )
97
+ }
98
+ </div>
99
+ );
100
+ };
101
+
102
+ export default AdvancedTableInlineEditing;
@@ -0,0 +1,4 @@
1
+ Inline Cell Editing can be achieved with a combination of our `TextInput` kit and the `customRenderer` method available through columnDefinitions.
2
+
3
+ Hover over any cell within the 'Scheduled Meetings' column to see the TextInput and type in to change values. Values can be saved by clicking away from the TextInput or by hitting 'Enter'.
4
+ See the code snippet below to see how this was achieved. Devs must manage state themselves as shown.
@@ -36,4 +36,5 @@ examples:
36
36
  - advanced_table_selectable_rows: Selectable Rows
37
37
  - advanced_table_selectable_rows_no_subrows: Selectable Rows (No Subrows)
38
38
  - advanced_table_selectable_rows_actions: Selectable Rows (With Actions)
39
- - advanced_table_selectable_rows_header: Selectable Rows (No Actions Bar)
39
+ - advanced_table_selectable_rows_header: Selectable Rows (No Actions Bar)
40
+ - advanced_table_inline_editing: Inline Cell Editing
@@ -20,4 +20,5 @@ export { default as AdvancedTableNoSubrows } from './_advanced_table_no_subrows.
20
20
  export { default as AdvancedTableSelectableRowsHeader } from './_advanced_table_selectable_rows_header.jsx'
21
21
  export { default as AdvancedTableSelectableRowsActions } from './_advanced_table_selectable_rows_actions.jsx'
22
22
  export { default as AdvancedTableTablePropsStickyHeader } from './_advanced_table_table_props_sticky_header.jsx'
23
- export { default as AdvancedTableColumnHeadersCustomCell } from './_advanced_table_column_headers_custom_cell.jsx'
23
+ export { default as AdvancedTableColumnHeadersCustomCell } from './_advanced_table_column_headers_custom_cell.jsx'
24
+ export { default as AdvancedTableInlineEditing } from './_advanced_table_inline_editing.jsx'
@@ -1,5 +1,6 @@
1
1
 
2
2
  import React from "react"
3
+ import ReactDOMServer from "react-dom/server"
3
4
  import classnames from "classnames"
4
5
  import { buildAriaProps, buildCss, buildDataProps } from "../utilities/props"
5
6
  import { globalProps } from "../utilities/globalProps"
@@ -10,6 +11,7 @@ import Detail from "../pb_detail/_detail"
10
11
  import Flex from "../pb_flex/_flex"
11
12
  import FlexItem from "../pb_flex/_flex_item"
12
13
  import Image from "../pb_image/_image"
14
+ import { getDefaultImage } from "./docs/default_image/utils"
13
15
 
14
16
  type EventHandler = (React.MouseEventHandler<HTMLElement>)
15
17
 
@@ -101,7 +103,7 @@ const EmptyState = (props: EmptyStateProps) => {
101
103
  lg: {
102
104
  vertical: {
103
105
  imageWidth: "100%",
104
- titleSize: 2,
106
+ titleSize: 1,
105
107
  titlePadding: "sm",
106
108
  descriptionPadding: "lg",
107
109
  buttonSize: "md",
@@ -125,7 +127,12 @@ const EmptyState = (props: EmptyStateProps) => {
125
127
  const configs = sizeConfigs[size]?.[orientation]
126
128
  const alignFlex = alignment === "center" ? "center" : alignment === "right" ? "end" : "start"
127
129
  const alignText = alignment === "center" ? "center" : alignment === "right" ? "right" : undefined
130
+ const imageSource = getDefaultImage().computer
128
131
 
132
+ const getSvgAsDataUrl = () => {
133
+ const svgString = ReactDOMServer.renderToStaticMarkup(imageSource)
134
+ return `data:image/svg+xml;base64,${window.btoa(svgString)}`
135
+ }
129
136
 
130
137
  const layout = (
131
138
  <div {...ariaProps}
@@ -140,13 +147,20 @@ const EmptyState = (props: EmptyStateProps) => {
140
147
  paddingRight="xl"
141
148
  vertical="center"
142
149
  >
143
- { image ? (
150
+
151
+ {image && image === 'default' ? (
152
+ <Image
153
+ alt="test"
154
+ htmlOptions={{ width: configs.imageWidth, height: "auto", alignment: "start" }}
155
+ url={getSvgAsDataUrl()}
156
+ />
157
+ ) : image && image ? (
144
158
  <Image
145
159
  alt="test"
146
160
  htmlOptions={{ width: configs.imageWidth, height: "auto", alignment: "start" }}
147
161
  url={image}
148
162
  />
149
- ) : null }
163
+ ) : null}
150
164
 
151
165
  <FlexItem >
152
166
  <Title paddingBottom={configs.titlePadding as "xxs" | "xs" | "sm" | undefined}
@@ -10,7 +10,7 @@ const EmptyStateAlignment = (props) => (
10
10
  alignment="left"
11
11
  description="Body text goes into detail with possible steps for user to take"
12
12
  header="Title Explains"
13
- image="https://component.gallery/static/8d36eaa25b6dcb026685101ebc379022/Empty%20state%20icon..svg"
13
+ image="default"
14
14
  primaryButton="Next Action"
15
15
  size="md"
16
16
  />
@@ -19,7 +19,7 @@ const EmptyStateAlignment = (props) => (
19
19
  alignment="center"
20
20
  description="Body text goes into detail with possible steps for user to take"
21
21
  header="Title Explains"
22
- image="https://component.gallery/static/8d36eaa25b6dcb026685101ebc379022/Empty%20state%20icon..svg"
22
+ image="default"
23
23
  primaryButton="Next Action"
24
24
  size="md"
25
25
  />
@@ -28,7 +28,7 @@ const EmptyStateAlignment = (props) => (
28
28
  alignment="right"
29
29
  description="Body text goes into detail with possible steps for user to take"
30
30
  header="Title Explains"
31
- image="https://component.gallery/static/8d36eaa25b6dcb026685101ebc379022/Empty%20state%20icon..svg"
31
+ image="default"
32
32
  primaryButton="Next Action"
33
33
  size="md"
34
34
  />
@@ -8,7 +8,7 @@ const EmptyStateOrientation = (props) => (
8
8
  alignment="left"
9
9
  description="Body text goes into detail with possible steps for user to take"
10
10
  header="Title Explains"
11
- image="https://component.gallery/static/8d36eaa25b6dcb026685101ebc379022/Empty%20state%20icon..svg"
11
+ image="default"
12
12
  orientation="horizontal"
13
13
  primaryButton="Next Action"
14
14
  size="lg"
@@ -10,7 +10,7 @@ const EmptyStateSize = (props) => (
10
10
  alignment="center"
11
11
  description="Body text goes into detail with possible steps for user to take"
12
12
  header="Title Explains"
13
- image="https://component.gallery/static/8d36eaa25b6dcb026685101ebc379022/Empty%20state%20icon..svg"
13
+ image="default"
14
14
  linkButton="Alt Action"
15
15
  onLinkButtonClick={() => alert("link button clicked!")}
16
16
  onPrimaryButtonClick={() => alert("primary button clicked!")}
@@ -22,7 +22,7 @@ const EmptyStateSize = (props) => (
22
22
  alignment="center"
23
23
  description="Body text goes into detail with possible steps for user to take"
24
24
  header="Title Explains"
25
- image="https://component.gallery/static/8d36eaa25b6dcb026685101ebc379022/Empty%20state%20icon..svg"
25
+ image="default"
26
26
  linkButton="Alt Action"
27
27
  onLinkButtonClick={() => alert("link button clicked!")}
28
28
  onPrimaryButtonClick={() => alert("primary button clicked!")}
@@ -0,0 +1,21 @@
1
+ <svg width="341" height="251" viewBox="0 0 341 251" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M13.1313 233.77C21.94 231.747 31.6491 231.91 39.5575 227.702C56.9777 218.433 60.9184 182.571 50.3011 169.333C34.3751 149.475 16.4759 166.95 24.5771 179.675C27.3943 184.1 33.7848 186.935 38.6891 188.18C78.9114 198.392 100.955 166.769 129.901 144.801C138.226 138.483 146.873 132.512 155.877 127.089C163.474 122.514 171.448 118.481 179.602 114.869C188.038 111.131 196.468 106.974 205.556 105.078C224.677 101.089 236.173 98.6398 255.712 97.8855C262.58 97.6204 277.133 100.039 283.642 102.064C288.211 103.484 292.636 105.371 296.804 107.625C301.093 109.944 305.182 112.643 308.894 115.718C312.887 119.025 316.534 122.729 319.806 126.678C322.7 130.169 325.327 133.915 327.309 137.936C329.482 142.346 331.21 147.008 332.182 151.791C333.078 156.199 331.253 169.896 330.164 174.281C327.718 184.135 304.022 184.256 296.804 179.675C279.554 168.727 298.876 138.498 305.389 130.376C320.884 111.048 335.049 101.555 330.164 75.5071C329.954 74.386 324.327 52.1211 318.598 47.6126C312.869 43.104 302.552 30.5147 289.885 30.1272" stroke="#DFE3E8" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="5 9"/>
3
+ <rect x="12.0342" y="231.969" width="240.667" height="16.9791" fill="white"/>
4
+ <path opacity="0.397871" fill-rule="evenodd" clip-rule="evenodd" d="M24.0396 232C25.6294 241.986 74.6993 250 135 250C195.3 250 244.37 241.986 245.96 232H24.0396Z" fill="#EFEFEF"/>
5
+ <path d="M12.0283 233.803H252.754V230.543L12.0283 230.543V233.803Z" fill="#DFE3E8"/>
6
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M111.452 145.308H235.589C238.589 145.308 241.021 147.74 241.021 150.741V233.985C241.021 236.986 238.589 239.418 235.589 239.418H111.452C108.452 239.418 106.02 236.986 106.02 233.985V150.741C106.02 147.74 108.452 145.308 111.452 145.308Z" fill="#E6EBEF"/>
7
+ <mask id="mask0_5923_12806" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="106" y="145" width="136" height="95">
8
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M111.452 145.308H235.589C238.589 145.308 241.021 147.74 241.021 150.741V233.985C241.021 236.986 238.589 239.418 235.589 239.418H111.452C108.452 239.418 106.02 236.986 106.02 233.985V150.741C106.02 147.74 108.452 145.308 111.452 145.308Z" fill="white"/>
9
+ </mask>
10
+ <g mask="url(#mask0_5923_12806)">
11
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M233.81 130.202L135.323 256.455H90.7475L80.9556 100.717L233.81 130.202Z" fill="#EFF3F6"/>
12
+ </g>
13
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M190.054 195.575L174.18 206.901V211.604C174.18 211.951 173.792 212.153 173.511 211.952L158.305 201.104L158.287 201.091C158.13 200.979 158.038 200.798 158.038 200.605V200.6V189.57V189.566C158.038 189.373 158.131 189.191 158.288 189.08L158.305 189.067L174.18 177.741V173.038C174.18 172.691 174.567 172.489 174.848 172.69L190.054 183.538L190.072 183.551C190.229 183.662 190.322 183.844 190.322 184.036V184.042V195.071V195.076C190.322 195.269 190.228 195.451 190.071 195.562L190.054 195.575Z" fill="#F9F9F9"/>
14
+ <path d="M174.18 206.901L173.308 205.679C172.914 205.961 172.68 206.416 172.68 206.901H174.18ZM190.054 195.575L190.925 196.796C190.932 196.791 190.938 196.787 190.945 196.782L190.054 195.575ZM173.511 211.952L174.383 210.732L174.382 210.731L173.511 211.952ZM158.305 201.104L157.425 202.319L157.434 202.325L158.305 201.104ZM158.287 201.091L159.167 199.876L159.159 199.87L158.287 201.091ZM158.288 189.08L159.158 190.302C159.165 190.297 159.172 190.292 159.179 190.286L158.288 189.08ZM158.305 189.067L157.434 187.846C157.427 187.85 157.421 187.855 157.414 187.86L158.305 189.067ZM174.18 177.741L175.051 178.962C175.445 178.681 175.68 178.226 175.68 177.741H174.18ZM174.848 172.69L173.976 173.91L173.977 173.911L174.848 172.69ZM190.054 183.538L190.934 182.323L190.925 182.317L190.054 183.538ZM190.072 183.551L189.192 184.766L189.203 184.774L190.072 183.551ZM190.071 195.562L189.201 194.34C189.194 194.345 189.188 194.35 189.181 194.355L190.071 195.562ZM175.051 208.122L190.925 196.796L189.183 194.354L173.308 205.679L175.051 208.122ZM175.68 211.604V206.901H172.68V211.604H175.68ZM172.639 213.173C173.929 214.094 175.68 213.15 175.68 211.604H172.68C172.68 210.751 173.654 210.211 174.383 210.732L172.639 213.173ZM157.434 202.325L172.64 213.173L174.382 210.731L159.176 199.883L157.434 202.325ZM157.407 202.305L157.425 202.319L159.185 199.889L159.167 199.876L157.407 202.305ZM156.538 200.605C156.538 201.281 156.863 201.917 157.415 202.312L159.159 199.87C159.398 200.041 159.538 200.316 159.538 200.605H156.538ZM156.538 200.6V200.605H159.538V200.6H156.538ZM156.538 189.57V200.6H159.538V189.57H156.538ZM156.538 189.566V189.57H159.538V189.566H156.538ZM157.418 187.857C156.864 188.252 156.538 188.889 156.538 189.566H159.538C159.538 189.856 159.398 190.131 159.158 190.302L157.418 187.857ZM157.414 187.86L157.397 187.873L159.179 190.286L159.196 190.274L157.414 187.86ZM173.308 176.52L157.434 187.846L159.176 190.288L175.051 178.962L173.308 176.52ZM172.68 173.038V177.741H175.68V173.038H172.68ZM175.72 171.469C174.43 170.548 172.68 171.492 172.68 173.038H175.68C175.68 173.891 174.705 174.431 173.976 173.91L175.72 171.469ZM190.925 182.317L175.719 171.469L173.977 173.911L189.183 184.759L190.925 182.317ZM190.953 182.337L190.934 182.323L189.174 184.753L189.192 184.766L190.953 182.337ZM191.822 184.036C191.822 183.363 191.498 182.724 190.941 182.328L189.203 184.774C188.96 184.601 188.822 184.324 188.822 184.036H191.822ZM191.822 184.042V184.036H188.822V184.042H191.822ZM191.822 195.071V184.042H188.822V195.071H191.822ZM191.822 195.076V195.071H188.822V195.076H191.822ZM190.941 196.785C191.495 196.39 191.822 195.752 191.822 195.076H188.822C188.822 194.786 188.961 194.511 189.201 194.34L190.941 196.785ZM190.945 196.782L190.962 196.769L189.181 194.355L189.164 194.368L190.945 196.782Z" fill="#DFE3E8"/>
15
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M236.947 145.308H111.452C108.452 145.308 106.02 147.74 106.02 150.741V233.985C106.02 236.986 108.452 239.418 111.452 239.418H236.947C239.947 239.418 242.38 236.986 242.38 233.985V150.741C242.38 147.74 239.947 145.308 236.947 145.308ZM109.279 150.741C109.279 149.541 110.252 148.568 111.452 148.568H236.947C238.147 148.568 239.12 149.541 239.12 150.741V233.985C239.12 235.185 238.147 236.158 236.947 236.158H111.452C110.252 236.158 109.279 235.185 109.279 233.985V150.741Z" fill="#DFE3E8"/>
16
+ <circle cx="272.814" cy="31.0862" r="6.5" transform="rotate(-58 272.814 31.0862)" stroke="#DFE3E8" stroke-width="3"/>
17
+ <path d="M269.32 17.8078L270.476 15.9575C270.911 15.2615 271.76 15.0988 272.345 15.4639L287.909 25.1895C288.493 25.5546 288.72 26.3898 288.285 27.0858L287.129 28.9361C286.694 29.6321 285.844 29.7949 285.259 29.4297L269.695 19.7042C269.111 19.339 268.885 18.5038 269.32 17.8078Z" stroke="#DFE3E8" stroke-width="3"/>
18
+ <path d="M271.277 14.9443L270.425 8.22099" stroke="#DFE3E8" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/>
19
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M268.414 18.3138L262.372 20.4343L268.414 18.3138Z" stroke="#DFE3E8" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/>
20
+ <circle cx="283.883" cy="13.9734" r="6.5" transform="rotate(-58 283.883 13.9734)" stroke="#DFE3E8" stroke-width="3"/>
21
+ </svg>
@@ -0,0 +1,122 @@
1
+ import React from "react";
2
+
3
+ const computer = (
4
+ <svg
5
+ fill="none"
6
+ height={251}
7
+ width={341}
8
+ xmlns="http://www.w3.org/2000/svg"
9
+ >
10
+ <path
11
+ d="M13.131 233.77c8.809-2.023 18.518-1.86 26.426-6.068 17.42-9.269 21.361-45.131 10.744-58.369-15.926-19.858-33.825-2.383-25.724 10.342 2.817 4.425 9.208 7.26 14.112 8.505 40.222 10.212 62.266-21.411 91.212-43.379 8.325-6.318 16.972-12.289 25.976-17.712 7.597-4.575 15.571-8.608 23.725-12.22 8.436-3.738 16.866-7.895 25.954-9.791 19.121-3.989 30.617-6.438 50.156-7.193 6.868-.265 21.421 2.154 27.93 4.179a73.8 73.8 0 0 1 13.162 5.561c4.289 2.319 8.378 5.018 12.09 8.093 3.993 3.307 7.64 7.011 10.912 10.96 2.894 3.491 5.521 7.237 7.503 11.258 2.173 4.41 3.901 9.072 4.873 13.855.896 4.408-.929 18.105-2.018 22.49-2.446 9.854-26.142 9.975-33.36 5.394-17.25-10.948 2.072-41.177 8.585-49.299 15.495-19.328 29.66-28.821 24.775-54.869-.21-1.121-5.837-23.386-11.566-27.894-5.729-4.509-16.046-17.098-28.713-17.486"
12
+ stroke="#DFE3E8"
13
+ strokeDasharray="5 9"
14
+ strokeLinecap="round"
15
+ strokeLinejoin="round"
16
+ strokeWidth={3}
17
+ />
18
+ <path d="M12.034 231.969h240.667v16.979H12.034z"
19
+ fill="#fff"
20
+ />
21
+ <path
22
+ clipRule="evenodd"
23
+ d="M24.04 232c1.59 9.986 50.66 18 110.96 18s109.37-8.014 110.96-18H24.04Z"
24
+ fill="#EFEFEF"
25
+ fillRule="evenodd"
26
+ opacity={0.398}
27
+ />
28
+ <path d="M12.028 233.803h240.726v-3.26H12.028v3.26Z"
29
+ fill="#DFE3E8"
30
+ />
31
+ <path
32
+ clipRule="evenodd"
33
+ d="M111.452 145.308h124.137c3 0 5.432 2.432 5.432 5.433v83.244a5.432 5.432 0 0 1-5.432 5.433H111.452c-3 0-5.432-2.432-5.432-5.433v-83.244a5.432 5.432 0 0 1 5.432-5.433Z"
34
+ fill="#E6EBEF"
35
+ fillRule="evenodd"
36
+ />
37
+ <mask
38
+ height={95}
39
+ id="a"
40
+ maskUnits="userSpaceOnUse"
41
+ style={{
42
+ maskType: "luminance",
43
+ }}
44
+ width={136}
45
+ x={106}
46
+ y={145}
47
+ >
48
+ <path
49
+ clipRule="evenodd"
50
+ d="M111.452 145.308h124.137c3 0 5.432 2.432 5.432 5.433v83.244a5.432 5.432 0 0 1-5.432 5.433H111.452c-3 0-5.432-2.432-5.432-5.433v-83.244a5.432 5.432 0 0 1 5.432-5.433Z"
51
+ fill="#fff"
52
+ fillRule="evenodd"
53
+ />
54
+ </mask>
55
+ <g mask="url(#a)">
56
+ <path
57
+ clipRule="evenodd"
58
+ d="m233.81 130.202-98.487 126.253H90.747l-9.791-155.738 152.854 29.485Z"
59
+ fill="#EFF3F6"
60
+ fillRule="evenodd"
61
+ />
62
+ </g>
63
+ <path
64
+ clipRule="evenodd"
65
+ d="m190.054 195.575-15.874 11.326v4.703a.423.423 0 0 1-.669.348l-15.206-10.848-.018-.013a.596.596 0 0 1-.249-.486v-11.039c0-.193.093-.375.25-.486l.017-.013 15.875-11.326v-4.703c0-.347.387-.549.668-.348l15.206 10.848.018.013c.157.111.25.293.25.485V195.076a.596.596 0 0 1-.251.486l-.017.013Z"
66
+ fill="#F9F9F9"
67
+ fillRule="evenodd"
68
+ />
69
+ <path
70
+ d="m174.18 206.901-.872-1.222a1.503 1.503 0 0 0-.628 1.222h1.5Zm15.874-11.326.871 1.221.02-.014-.891-1.207Zm-16.543 16.377.872-1.22-.001-.001-.871 1.221Zm-15.206-10.848-.88 1.215.009.006.871-1.221Zm-.018-.013.88-1.215-.008-.006-.872 1.221Zm.001-12.011.87 1.222.021-.016-.891-1.206Zm.017-.013-.871-1.221-.02.014.891 1.207Zm15.875-11.326.871 1.221a1.5 1.5 0 0 0 .629-1.221h-1.5Zm.668-5.051-.872 1.22.001.001.871-1.221Zm15.206 10.848.88-1.215-.009-.006-.871 1.221Zm.018.013-.88 1.215.011.008.869-1.223Zm-.001 12.011-.87-1.222-.02.015.89 1.207Zm-15.02 12.56 15.874-11.326-1.742-2.442-15.875 11.325 1.743 2.443Zm.629 3.482v-4.703h-3v4.703h3Zm-3.041 1.569c1.29.921 3.041-.023 3.041-1.569h-3c0-.853.974-1.393 1.703-.872l-1.744 2.441Zm-15.205-10.848 15.206 10.848 1.742-2.442-15.206-10.848-1.742 2.442Zm-.027-.02.018.014 1.76-2.43-.018-.013-1.76 2.429Zm-.869-1.7c0 .676.325 1.312.877 1.707l1.744-2.442a.905.905 0 0 1 .379.735h-3Zm0-.005v.005h3v-.005h-3Zm0-11.03v11.03h3v-11.03h-3Zm0-.004v.004h3v-.004h-3Zm.88-1.709a2.098 2.098 0 0 0-.88 1.709h3c0 .29-.14.565-.38.736l-1.74-2.445Zm-.004.003-.017.013 1.782 2.413.017-.012-1.782-2.414Zm15.894-11.34-15.874 11.326 1.742 2.442 15.875-11.326-1.743-2.442Zm-.628-3.482v4.703h3v-4.703h-3Zm3.04-1.569c-1.29-.921-3.04.023-3.04 1.569h3c0 .853-.975 1.393-1.704.872l1.744-2.441Zm15.205 10.848-15.206-10.848-1.742 2.442 15.206 10.848 1.742-2.442Zm.028.02-.019-.014-1.76 2.43.018.013 1.761-2.429Zm.869 1.699c0-.673-.324-1.312-.881-1.708l-1.738 2.446a.906.906 0 0 1-.381-.738h3Zm0 .006v-.006h-3v.006h3Zm0 11.029v-11.029h-3v11.029h3Zm0 .005v-.005h-3v.005h3Zm-.881 1.709a2.1 2.1 0 0 0 .881-1.709h-3c0-.29.139-.565.379-.736l1.74 2.445Zm.004-.003.017-.013-1.781-2.414-.017.013 1.781 2.414Z"
71
+ fill="#DFE3E8"
72
+ />
73
+ <path
74
+ clipRule="evenodd"
75
+ d="M236.947 145.308H111.452c-3 0-5.432 2.432-5.432 5.433v83.244a5.432 5.432 0 0 0 5.432 5.433h125.495c3 0 5.433-2.432 5.433-5.433v-83.244a5.433 5.433 0 0 0-5.433-5.433Zm-127.668 5.433c0-1.2.973-2.173 2.173-2.173h125.495c1.2 0 2.173.973 2.173 2.173v83.244c0 1.2-.973 2.173-2.173 2.173H111.452c-1.2 0-2.173-.973-2.173-2.173v-83.244Z"
76
+ fill="#DFE3E8"
77
+ fillRule="evenodd"
78
+ />
79
+ <circle
80
+ cx={272.814}
81
+ cy={31.086}
82
+ r={6.5}
83
+ stroke="#DFE3E8"
84
+ strokeWidth={3}
85
+ transform="rotate(-58 272.814 31.086)"
86
+ />
87
+ <path
88
+ d="m269.32 17.808 1.156-1.85c.435-.697 1.284-.86 1.869-.494l15.564 9.725c.584.366.811 1.2.376 1.897l-1.156 1.85c-.435.696-1.285.859-1.87.494l-15.564-9.726c-.584-.365-.81-1.2-.375-1.896Z"
89
+ stroke="#DFE3E8"
90
+ strokeWidth={3}
91
+ />
92
+ <path
93
+ d="m271.277 14.944-.852-6.723"
94
+ stroke="#DFE3E8"
95
+ strokeLinecap="round"
96
+ strokeLinejoin="round"
97
+ strokeWidth={4}
98
+ />
99
+ <path
100
+ clipRule="evenodd"
101
+ d="m268.414 18.314-6.042 2.12 6.042-2.12Z"
102
+ stroke="#DFE3E8"
103
+ strokeLinecap="round"
104
+ strokeLinejoin="round"
105
+ strokeWidth={4}
106
+ />
107
+ <circle
108
+ cx={283.883}
109
+ cy={13.973}
110
+ r={6.5}
111
+ stroke="#DFE3E8"
112
+ strokeWidth={3}
113
+ transform="rotate(-58 283.883 13.973)"
114
+ />
115
+ </svg>
116
+ )
117
+
118
+ export const getDefaultImage = () => {
119
+ return {
120
+ computer,
121
+ }
122
+ }
@@ -25,7 +25,7 @@
25
25
  <%= pb_form_with(scope: :example, url: "", method: :get) do |form| %>
26
26
  <%= form.typeahead :example_typeahead, props: { data: { typeahead_example1: true, user: {} }, label: true, placeholder: "Search for a user" } %>
27
27
  <%= form.text_field :example_text_field, props: { label: true } %>
28
- <%= form.phone_number_field :example_phone_number_field, props: { label: "Example phone field" } %>
28
+ <%= form.phone_number_field :example_phone_number_field, props: { label: "Example phone field", hidden_inputs: true } %>
29
29
  <%= form.email_field :example_email_field, props: { label: true } %>
30
30
  <%= form.number_field :example_number_field, props: { label: true } %>
31
31
  <%= form.search_field :example_search_field, props: { label: true } %>
@@ -24,7 +24,7 @@
24
24
  <%= pb_form_with(scope: :example, method: :get, url: "", validate: true) do |form| %>
25
25
  <%= form.typeahead :example_typeahead_validation, props: { data: { typeahead_example2: true, user: {} }, label: true, placeholder: "Search for a user", required: true, validation: { message: "Please select a user." } } %>
26
26
  <%= form.text_field :example_text_field_validation, props: { label: true, required: true } %>
27
- <%= form.phone_number_field :example_phone_number_field_validation, props: { label: "Example phone field" } %>
27
+ <%= form.phone_number_field :example_phone_number_field_validation, props: { label: "Example phone field", hidden_inputs: true } %>
28
28
  <%= form.email_field :example_email_field_validation, props: { label: true, required: true } %>
29
29
  <%= form.number_field :example_number_field_validation, props: { label: true, required: true } %>
30
30
  <%= form.search_field :example_project_number_validation, props: { label: true, required: true, validation: { pattern: "[0-9]{2}-[0-9]{5}", message: "Please enter a valid project number (example: 33-12345)." } } %>
@@ -49,7 +49,7 @@ const IconButton = (props: IconButtonProps) => {
49
49
  id={id}
50
50
  >
51
51
  <Button
52
- borderRadius="lg"
52
+ borderRadius="xs"
53
53
  htmlType={htmlType}
54
54
  link={link}
55
55
  newWindow={newWindow}
@@ -4,7 +4,7 @@
4
4
  new_window:object.new_window,
5
5
  target: object.target,
6
6
  dark: object.dark,
7
- border_radius: "lg" }) do %>
7
+ border_radius: "xs" }) do %>
8
8
  <%= pb_rails("icon", props: { icon: object.icon,
9
9
  fixed_width: true,
10
10
  dark: object.dark,
@@ -1,4 +1,4 @@
1
- import React, { useState, useEffect, useRef } from "react";
1
+ import React, { useState, useEffect, useRef, forwardRef } from "react";
2
2
  import classnames from "classnames";
3
3
  import { globalProps, GlobalProps } from "../utilities/globalProps";
4
4
  import {
@@ -23,6 +23,13 @@ import {
23
23
  getExpandedItems,
24
24
  } from "./_helper_functions";
25
25
 
26
+ interface MultiLevelSelectComponent
27
+ extends React.ForwardRefExoticComponent<
28
+ MultiLevelSelectProps & React.RefAttributes<HTMLInputElement>
29
+ > {
30
+ Options: typeof MultiLevelSelectOptions;
31
+ }
32
+
26
33
  type MultiLevelSelectProps = {
27
34
  aria?: { [key: string]: string }
28
35
  className?: string
@@ -35,6 +42,7 @@ type MultiLevelSelectProps = {
35
42
  name?: string
36
43
  returnAllSelected?: boolean
37
44
  treeData?: { [key: string]: string; }[] | any
45
+ onChange?: (event: { target: { name?: string; value: any } }) => void
38
46
  onSelect?: (prop: { [key: string]: any }) => void
39
47
  selectedIds?: string[] | any
40
48
  variant?: "multi" | "single"
@@ -42,7 +50,7 @@ type MultiLevelSelectProps = {
42
50
  pillColor?: "primary" | "neutral" | "success" | "warning" | "error" | "info" | "data_1" | "data_2" | "data_3" | "data_4" | "data_5" | "data_6" | "data_7" | "data_8" | "windows" | "siding" | "roofing" | "doors" | "gutters" | "solar" | "insulation" | "accessories",
43
51
  } & GlobalProps
44
52
 
45
- const MultiLevelSelect = (props: MultiLevelSelectProps) => {
53
+ const MultiLevelSelect = forwardRef<HTMLInputElement, MultiLevelSelectProps>((props) => {
46
54
  const {
47
55
  aria = {},
48
56
  className,
@@ -55,6 +63,7 @@ const MultiLevelSelect = (props: MultiLevelSelectProps) => {
55
63
  name,
56
64
  returnAllSelected = false,
57
65
  treeData,
66
+ onChange = () => null,
58
67
  onSelect = () => null,
59
68
  selectedIds,
60
69
  variant = "multi",
@@ -287,8 +296,10 @@ const MultiLevelSelect = (props: MultiLevelSelectProps) => {
287
296
  // Logic for removing items from returnArray or defaultReturn when pills clicked
288
297
  if (returnAllSelected) {
289
298
  onSelect(getCheckedItems(updatedTree));
299
+ onChange({ target: { name, value: getCheckedItems(updatedTree) } });
290
300
  } else {
291
301
  onSelect(getDefaultCheckedItems(updatedTree));
302
+ onChange({ target: { name, value: getDefaultCheckedItems(updatedTree) } });
292
303
  }
293
304
  };
294
305
 
@@ -314,8 +325,10 @@ const MultiLevelSelect = (props: MultiLevelSelectProps) => {
314
325
  const updatedTree = changeItem(filtered[0], check);
315
326
  if (returnAllSelected) {
316
327
  onSelect(getCheckedItems(updatedTree));
328
+ onChange({ target: { name, value: getCheckedItems(updatedTree) } });
317
329
  } else {
318
330
  onSelect(getDefaultCheckedItems(updatedTree));
331
+ onChange({ target: { name, value: getDefaultCheckedItems(updatedTree) } });
319
332
  }
320
333
  };
321
334
 
@@ -348,6 +361,7 @@ const MultiLevelSelect = (props: MultiLevelSelectProps) => {
348
361
  setIsDropdownClosed(true);
349
362
 
350
363
  onSelect(selectedItem);
364
+ onChange({ target: { name, value: selectedItem } });
351
365
  };
352
366
 
353
367
  // Single select: reset the tree state upon typing
@@ -389,12 +403,12 @@ const MultiLevelSelect = (props: MultiLevelSelectProps) => {
389
403
  // Rendering formattedData to UI based on typeahead
390
404
  const renderNestedOptions = (items: { [key: string]: string; }[] | any ) => {
391
405
  const hasOptionsChild = React.Children.toArray(props.children).some(
392
- (child: any) => child.type === MultiLevelSelect.Options
406
+ (child) => React.isValidElement(child) && child.type === MultiLevelSelect.Options
393
407
  );
394
408
 
395
409
  if (hasOptionsChild) {
396
410
  return React.Children.map(props.children, (child) => {
397
- if (child.type === MultiLevelSelect.Options) {
411
+ if (React.isValidElement(child) && child.type === MultiLevelSelect.Options) {
398
412
  return React.cloneElement(child, { items });
399
413
  }
400
414
  return null;
@@ -459,6 +473,18 @@ const MultiLevelSelect = (props: MultiLevelSelectProps) => {
459
473
  ))
460
474
  : null}
461
475
 
476
+ {!returnAllSelected
477
+ ? defaultReturn.map((item) => (
478
+ <input
479
+ disabled={disabled}
480
+ key={item.id}
481
+ name={`${name}[]`}
482
+ type="hidden"
483
+ value={item.id}
484
+ />
485
+ ))
486
+ : null}
487
+
462
488
  {returnAllSelected &&
463
489
  returnedArray.length !== 0 &&
464
490
  inputDisplay === "pills"
@@ -547,8 +573,9 @@ const MultiLevelSelect = (props: MultiLevelSelectProps) => {
547
573
  </MultiLevelSelectContext.Provider>
548
574
  </div>
549
575
  );
550
- };
576
+ }) as MultiLevelSelectComponent;
551
577
 
578
+ MultiLevelSelect.displayName = "MultiLevelSelect";
552
579
  MultiLevelSelect.Options = MultiLevelSelectOptions;
553
580
 
554
581
  export default MultiLevelSelect;