playbook_ui 16.8.0.pre.alpha.PLAY296916758 → 16.8.0.pre.alpha.PLAY298516633

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 (44) hide show
  1. checksums.yaml +4 -4
  2. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_sticky_header.jsx +4 -12
  3. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_sticky_header.md +0 -4
  4. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_sticky_header_rails.html.erb +2 -16
  5. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_sticky_header_rails.md +0 -4
  6. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_table_props_sticky_header.html.erb +2 -16
  7. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_table_props_sticky_header.jsx +5 -12
  8. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_table_props_sticky_header_rails.md +0 -4
  9. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_table_props_sticky_header_react.md +3 -5
  10. data/app/pb_kits/playbook/pb_advanced_table/docs/example.yml +0 -2
  11. data/app/pb_kits/playbook/pb_advanced_table/docs/index.js +0 -1
  12. data/app/pb_kits/playbook/pb_date_picker/date_picker.html.erb +21 -36
  13. data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_dialog_submission.jsx +2 -2
  14. data/app/pb_kits/playbook/pb_dropdown/_dropdown.tsx +58 -0
  15. data/app/pb_kits/playbook/pb_dropdown/dropdown.html.erb +2 -0
  16. data/app/pb_kits/playbook/pb_dropdown/dropdown.test.jsx +7 -1
  17. data/app/pb_kits/playbook/pb_icon/_icon.scss +1 -2
  18. data/app/pb_kits/playbook/pb_passphrase/kit.schema.json +0 -13
  19. data/app/pb_kits/playbook/pb_passphrase/passphrase.html.erb +1 -70
  20. data/app/pb_kits/playbook/pb_passphrase/passphrase.rb +0 -70
  21. data/app/pb_kits/playbook/pb_select/select.rb +9 -0
  22. data/app/pb_kits/playbook/pb_table/docs/_table_sticky.html.erb +83 -85
  23. data/app/pb_kits/playbook/pb_table/docs/_table_sticky.jsx +86 -88
  24. data/app/pb_kits/playbook/pb_table/docs/_table_sticky.md +1 -3
  25. data/app/pb_kits/playbook/pb_table/docs/_table_with_filter_variant_external_filter_rails.md +1 -1
  26. data/app/pb_kits/playbook/pb_text_input/_text_input.scss +0 -37
  27. data/app/pb_kits/playbook/pb_text_input/text_input.rb +9 -0
  28. data/dist/chunks/{_pb_line_graph-CRAinmKY.js → _pb_line_graph-BgsTI0CL.js} +1 -1
  29. data/dist/chunks/_typeahead-DA__Kgp5.js +5 -0
  30. data/dist/chunks/{globalProps-H163Gkjg.js → globalProps-DOB47YGB.js} +1 -1
  31. data/dist/chunks/{lib-BrCrUzC6.js → lib-BzglXly2.js} +1 -1
  32. data/dist/chunks/vendor.js +4 -4
  33. data/dist/menu.yml +3 -3
  34. data/dist/playbook-rails-react-bindings.js +1 -1
  35. data/dist/playbook-rails.js +1 -1
  36. data/dist/playbook.css +1 -1
  37. data/lib/playbook/version.rb +1 -1
  38. metadata +6 -11
  39. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_enable_toggle_expansion_rails.html.erb +0 -62
  40. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_enable_toggle_expansion_rails.md +0 -7
  41. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_sticky_scroll_limitation.jsx +0 -68
  42. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_sticky_scroll_limitation.md +0 -7
  43. data/app/pb_kits/playbook/pb_passphrase/index.ts +0 -58
  44. data/dist/chunks/_typeahead-DWYyolFR.js +0 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 90d3f24d9b712247bfd1f98152216cf8677f2e479b6bcc3c41fd6d5b8e7bd3f3
4
- data.tar.gz: 07d19fe6dbce4f09207d76da40552a143acf8554dc40f9d531037a540741a21c
3
+ metadata.gz: 0c5280f5836774dc50feecbf9578d7e722119d6fd9ff513a84b876a35951df9c
4
+ data.tar.gz: 0ab41db8c2fd90bf1eaee79e802026c72ea3284f1b9d1087585c8360baa4bf8b
5
5
  SHA512:
6
- metadata.gz: bb8b1924408a0f70f8cd6d8fa68b0e8cdac329ba7ce8477e337527f44012fbc30a350f7b3fc1a403e900fdd85d2ae326e3276c5dcd724ccfa2e33fc29d102038
7
- data.tar.gz: 679a8bbd8292b31d80cf2001881eec260e16459fea1711df3c1742246481b47e3330704513bdad9d332b642f5417bf2bfeb62462dd1e8907b129195f147db02c
6
+ metadata.gz: ead83210669d997f2038e735566712e0e14c85d441da394b7f4cb44d84bf09daab2410d2ef9f46d07702b1bba39c3a58036b849fcb2bf05db9b8a198a1afe460
7
+ data.tar.gz: 4ebba7adbd63c76bfef5aea82be2fa03b1f2226eb07fc8efb1bce065a9ffb14f33f0d16d7e45f0d83f8c0aa209ee9e17cba9a1a02b257da4d0a402391728a731
@@ -1,21 +1,13 @@
1
1
  import React from "react"
2
2
  import AdvancedTable from '../../pb_advanced_table/_advanced_table'
3
-
4
- const tableData = Array.from({ length: 15 }, (_, index) => ({
5
- year: String(2020 + index),
6
- newEnrollments: String(20 + index),
7
- scheduledMeetings: String(10 + index),
8
- attendanceRate: `${50 + index}%`,
9
- completedClasses: String(3 + index),
10
- classCompletionRate: `${30 + index}%`,
11
- graduatedStudents: String(19 + index),
12
- }))
3
+ import MOCK_DATA from "./advanced_table_mock_data.json"
13
4
 
14
5
  const AdvancedTableStickyHeader = (props) => {
15
6
  const columnDefinitions = [
16
7
  {
17
8
  accessor: "year",
18
9
  label: "Year",
10
+ cellAccessors: ["quarter", "month", "day"],
19
11
  },
20
12
  {
21
13
  accessor: "newEnrollments",
@@ -48,11 +40,11 @@ const AdvancedTableStickyHeader = (props) => {
48
40
  }
49
41
 
50
42
  return (
51
- <div style={{ maxHeight: "320px", overflowY: "auto" }}>
43
+ <div>
52
44
  <AdvancedTable
53
45
  columnDefinitions={columnDefinitions}
54
46
  responsive="none"
55
- tableData={tableData}
47
+ tableData={MOCK_DATA}
56
48
  tableProps={tableProps}
57
49
  {...props}
58
50
  />
@@ -1,7 +1,3 @@
1
1
  The `TableProps` prop can also be used to render a sticky header for the Advanced Table.
2
2
 
3
- This doc example uses a scroll container with flat rows so sticky behavior is visible in the docs without expanding subrows. Scroll inside the preview to see the header stick.
4
-
5
- This example builds flat table data inline for the docs preview. For typical `tableData` setup, see [Default (Required Props)](/kits/advanced_table/default/react#advanced_table_default).
6
-
7
3
  This doc example showcases how to set a sticky header for a nonresponsive table (see the `responsive` prop set to "none"). To achieve sticky header AND responsive functionality, see the "Sticky Header for Responsive Table" doc example below.
@@ -2,6 +2,7 @@
2
2
  {
3
3
  accessor: "year",
4
4
  label: "Year",
5
+ cellAccessors: ["quarter", "month", "day"],
5
6
  },
6
7
  {
7
8
  accessor: "newEnrollments",
@@ -29,19 +30,4 @@
29
30
  }
30
31
  ] %>
31
32
 
32
- <% table_data = 15.times.map do |index|
33
- {
34
- year: (2020 + index).to_s,
35
- id: (2020 + index).to_s,
36
- newEnrollments: (20 + index).to_s,
37
- scheduledMeetings: (10 + index).to_s,
38
- attendanceRate: "#{50 + index}%",
39
- completedClasses: (3 + index).to_s,
40
- classCompletionRate: "#{30 + index}%",
41
- graduatedStudents: (19 + index).to_s,
42
- }
43
- end %>
44
-
45
- <div style="max-height: 320px; overflow-y: auto;">
46
- <%= pb_rails("advanced_table", props: { id: "sticky_header_table", table_data: table_data, column_definitions: column_definitions, responsive: "none", table_props: { sticky: true }}) %>
47
- </div>
33
+ <%= pb_rails("advanced_table", props: { id: "sticky_header_table", table_data: @table_data, column_definitions: column_definitions, responsive: "none", table_props: { sticky: true }}) %>
@@ -1,7 +1,3 @@
1
1
  The `table_props` prop can also be used to render a sticky header for the Advanced Table.
2
2
 
3
- This doc example uses a scroll container with flat rows so sticky behavior is visible in the docs without expanding subrows. Scroll inside the preview to see the header stick.
4
-
5
- This example builds flat table data inline for the docs preview. For typical `table_data` setup, see [Default (Required Props)](/kits/advanced_table/default/rails#advanced_table_beta).
6
-
7
3
  This doc example showcases how to set a sticky header for a nonresponsive table (see the `responsive` prop set to "none"). To achieve sticky header AND responsive functionality, see the "[Sticky Header for Responsive Table](https://playbook.powerapp.cloud/kits/advanced_table/react#sticky-header-for-responsive-table)" doc example below.
@@ -2,6 +2,7 @@
2
2
  {
3
3
  accessor: "year",
4
4
  label: "Year",
5
+ cellAccessors: ["quarter", "month", "day"],
5
6
  },
6
7
  {
7
8
  accessor: "newEnrollments",
@@ -29,19 +30,4 @@
29
30
  }
30
31
  ] %>
31
32
 
32
- <% table_data = 15.times.map do |index|
33
- {
34
- year: (2020 + index).to_s,
35
- id: (2020 + index).to_s,
36
- newEnrollments: (20 + index).to_s,
37
- scheduledMeetings: (10 + index).to_s,
38
- attendanceRate: "#{50 + index}%",
39
- completedClasses: (3 + index).to_s,
40
- classCompletionRate: "#{30 + index}%",
41
- graduatedStudents: (19 + index).to_s,
42
- }
43
- end %>
44
-
45
- <div style="max-height: 320px; overflow-y: auto;">
46
- <%= pb_rails("advanced_table", props: { id: "table_props_sticky_table", table_data: table_data, column_definitions: column_definitions, table_props: { sticky: true }}) %>
47
- </div>
33
+ <%= pb_rails("advanced_table", props: { id: "table_props_sticky_table", table_data: @table_data, column_definitions: column_definitions, max_height: "xs", table_props: { sticky: true }}) %>
@@ -1,21 +1,13 @@
1
1
  import React from "react"
2
2
  import AdvancedTable from '../../pb_advanced_table/_advanced_table'
3
-
4
- const tableData = Array.from({ length: 15 }, (_, index) => ({
5
- year: String(2020 + index),
6
- newEnrollments: String(20 + index),
7
- scheduledMeetings: String(10 + index),
8
- attendanceRate: `${50 + index}%`,
9
- completedClasses: String(3 + index),
10
- classCompletionRate: `${30 + index}%`,
11
- graduatedStudents: String(19 + index),
12
- }))
3
+ import MOCK_DATA from "./advanced_table_mock_data.json"
13
4
 
14
5
  const AdvancedTableTablePropsStickyHeader = (props) => {
15
6
  const columnDefinitions = [
16
7
  {
17
8
  accessor: "year",
18
9
  label: "Year",
10
+ cellAccessors: ["quarter", "month", "day"],
19
11
  },
20
12
  {
21
13
  accessor: "newEnrollments",
@@ -48,10 +40,11 @@ const AdvancedTableTablePropsStickyHeader = (props) => {
48
40
  }
49
41
 
50
42
  return (
51
- <div style={{ maxHeight: "320px", overflowY: "auto" }}>
43
+ <div>
52
44
  <AdvancedTable
53
45
  columnDefinitions={columnDefinitions}
54
- tableData={tableData}
46
+ maxHeight="xs"
47
+ tableData={MOCK_DATA}
55
48
  tableProps={tableProps}
56
49
  {...props}
57
50
  />
@@ -2,10 +2,6 @@ Create a sticky header that works for responsive Advanced Tables by setting `sti
2
2
 
3
3
  **NOTE**: This behavior requires a `max_height` to work. The header is sticky within the table container, allowing for it to work along with the first column stickiness of a responsive table on smaller screen sizes.
4
4
 
5
- Scroll inside the table preview to see the header stick.
6
-
7
- This example builds flat table data inline for the docs preview. For typical `table_data` setup, see [Default (Required Props)](/kits/advanced_table/default/rails#advanced_table_beta).
8
-
9
5
  Expand the table above to see this in action.
10
6
 
11
7
  A sticky header on a nonresponsive table is demonstrated in the ["Sticky Header"](https://playbook.powerapp.cloud/kits/advanced_table#sticky-header) doc example above.
@@ -1,9 +1,7 @@
1
- Create a sticky header that works for responsive Advanced Tables by setting `sticky: true` via `tableProps` and wrapping the table in a scroll container (or using `maxHeight`).
1
+ Create a sticky header that works for responsive Advanced Tables by setting `sticky: true` via `tableProps` and giving the AdvancedTable a `maxHeight` using our [Max Height](https://playbook.powerapp.cloud/global_props/max_height) global prop.
2
2
 
3
- **NOTE**: The header is sticky within the table scroll area. The live example uses flat rows so you can scroll inside the preview without expanding subrows.
3
+ **NOTE**: This behavior requires a `maxHeight` to work. The header is sticky within the table container, allowing for it to work along with the first column stickiness of a responsive table on smaller screen sizes.
4
4
 
5
- This example builds flat table data inline for the docs preview. For typical `tableData` setup, see [Default (Required Props)](/kits/advanced_table/default/react#advanced_table_default).
6
-
7
- Expand the table above to see responsive behavior in action.
5
+ Expand the table above to see this in action.
8
6
 
9
7
  A sticky header on a nonresponsive table is demonstrated in the ["Sticky Header"](https://playbook.powerapp.cloud/kits/advanced_table/react#sticky-header) doc example above.
@@ -3,7 +3,6 @@ examples:
3
3
  - advanced_table_beta: Default (Required Props)
4
4
  - advanced_table_loading: Loading State
5
5
  - advanced_table_beta_subrow_headers: SubRow Headers
6
- - advanced_table_enable_toggle_expansion_rails: Enable Toggle Expansion
7
6
  - advanced_table_collapsible_trail_rails: Collapsible Trail
8
7
  - advanced_table_table_props: Table Props
9
8
  - advanced_table_sticky_header_rails: Sticky Header
@@ -53,7 +52,6 @@ examples:
53
52
  - advanced_table_table_props_sticky_header: Sticky Header for Responsive Table
54
53
  - advanced_table_sticky_columns: Sticky Columns
55
54
  - advanced_table_sticky_columns_and_header: Sticky Columns with Sticky Header
56
- - advanced_table_sticky_scroll_limitation: Sticky Header and Column Scroll Limitation
57
55
  - advanced_table_responsive: Responsive Tables
58
56
  - advanced_table_custom_cell: Custom Components for Cells
59
57
  - advanced_table_with_custom_header: Custom Header Cell
@@ -27,7 +27,6 @@ export { default as AdvancedTableFullscreen } from './_advanced_table_fullscreen
27
27
  export { default as AdvancedTableStickyColumns } from './_advanced_table_sticky_columns.jsx'
28
28
  export { default as AdvancedTableStickyHeader } from './_advanced_table_sticky_header.jsx'
29
29
  export { default as AdvancedTableStickyColumnsAndHeader } from './_advanced_table_sticky_columns_and_header.jsx'
30
- export { default as AdvancedTableStickyScrollLimitation } from './_advanced_table_sticky_scroll_limitation.jsx'
31
30
  export { default as AdvancedTableExpandByDepth } from './_advanced_table_expand_by_depth.jsx'
32
31
  export { default as AdvancedTableColumnBorderColor} from './_advanced_table_column_border_color.jsx'
33
32
  export { default as AdvancedTableColumnVisibility } from './_advanced_table_column_visibility.jsx'
@@ -79,57 +79,42 @@
79
79
 
80
80
  <%= javascript_tag do %>
81
81
  (function() {
82
- const initQuickPickChangeListener = (input) => {
83
- if (!<%= object.selection_type == "quickpick" %>) return
84
- if (input.dataset.quickpickInitialized) return
85
-
86
- input.dataset.quickpickInitialized = "true"
87
- input.addEventListener("change", ({ target }) => {
88
- const startDate = document.getElementById("<%= object.start_date_id %>")
89
- const endDate = document.getElementById("<%= object.end_date_id %>")
90
- const splittedValue = target.value.split(" to ")
91
- startDate.value = splittedValue[0]
92
- endDate.value = splittedValue[1] ? splittedValue[1] : splittedValue[0]
93
- })
94
- }
95
-
96
82
  const loadDatePicker = () => {
97
- const input = document.getElementById("<%= object.picker_id %>")
98
-
99
- if (!input || input._flatpickr) return true
100
- if (typeof window.datePickerHelper !== "function") return false
101
-
102
- window.datePickerHelper(<%= object.date_picker_config %>, "<%= object.scroll_container %>")
103
- initQuickPickChangeListener(input)
104
-
105
- return true
106
- }
107
-
108
- let attempts = 0
109
- const retryLoad = () => {
110
- if (loadDatePicker()) return
83
+ const input = document.getElementById("<%= object.picker_id %>");
84
+ if (input && !input._flatpickr) {
85
+ datePickerHelper(<%= object.date_picker_config %>, "<%= object.scroll_container %>")
111
86
 
112
- if (attempts++ < 20) {
113
- setTimeout(retryLoad, 100)
87
+ if (<%= object.selection_type == "quickpick" %>) {
88
+ document.getElementById("<%= object.picker_id %>").addEventListener("change", ({ target }) => {
89
+ const startDate = document.getElementById("<%= object.start_date_id %>")
90
+ const endDate = document.getElementById("<%= object.end_date_id %>")
91
+ const splittedValue = target.value.split(" to ")
92
+ startDate.value = splittedValue[0]
93
+ endDate.value = splittedValue[1] ? splittedValue[1] : splittedValue[0]
94
+ })
95
+ }
114
96
  }
115
97
  }
116
98
 
99
+ // Try to initialize immediately if DOM is ready
117
100
  if (document.readyState === "loading") {
118
- window.addEventListener("DOMContentLoaded", retryLoad)
101
+ window.addEventListener("DOMContentLoaded", loadDatePicker)
119
102
  } else {
120
- retryLoad()
103
+ loadDatePicker()
121
104
  }
122
105
 
123
106
  // For dynamically added content (modals, etc.), check again after a brief delay
124
107
  setTimeout(() => {
125
- const input = document.getElementById("<%= object.picker_id %>")
108
+ const input = document.getElementById("<%= object.picker_id %>");
126
109
  if (input && !input._flatpickr) {
127
- retryLoad()
110
+ loadDatePicker();
128
111
  }
129
- }, 100)
112
+ }, 100);
130
113
 
131
114
  if (<%= !object.custom_event_type.empty? %>) {
132
- window.addEventListener("<%= object.custom_event_type %>", retryLoad)
115
+ window.addEventListener("<%= object.custom_event_type %>", () => {
116
+ loadDatePicker()
117
+ })
133
118
  }
134
119
  })()
135
120
  <% end %>
@@ -36,10 +36,10 @@ const DatePickerDialogSubmission = () => {
36
36
  <Dialog.Body>
37
37
  <DatePicker
38
38
  defaultDate={dateFixed || undefined}
39
- key={"fixed-" + pickerInstance}
39
+ key={`fixed-${pickerInstance}`}
40
40
  label="Date"
41
41
  onChange={(dateStr) => setDateFixed(dateStr || "")}
42
- pickerId={"datePickerFixed-" + pickerInstance}
42
+ pickerId={`datePickerFixed-${pickerInstance}`}
43
43
  staticPosition={false}
44
44
  />
45
45
  </Dialog.Body>
@@ -21,6 +21,58 @@ import {
21
21
  handleClickOutside,
22
22
  } from "./utilities";
23
23
 
24
+ function serializeDropdownFilterResetDefault(
25
+ variant: "default" | "subtle" | "quickpick" | undefined,
26
+ multiSelect: boolean,
27
+ defaultValue: GenericObject | GenericObject[] | string | undefined,
28
+ dropdownOptions: GenericObject[] | GenericObject | undefined,
29
+ ): string | undefined {
30
+ const optionList: GenericObject[] = Array.isArray(dropdownOptions)
31
+ ? dropdownOptions
32
+ : [];
33
+ const optionDefaultId = (option: GenericObject | undefined): string | undefined => {
34
+ if (!option) return undefined;
35
+
36
+ const id = option.id;
37
+ if (id != null && id !== "") return String(id);
38
+
39
+ const matched = optionList.find((listOption: GenericObject) => (
40
+ (option.value != null && listOption.value === option.value) ||
41
+ (option.label != null && listOption.label === option.label)
42
+ ));
43
+
44
+ if (matched?.id != null && matched.id !== "") return String(matched.id);
45
+ return undefined;
46
+ };
47
+
48
+ if (variant === "quickpick") {
49
+ if (typeof defaultValue === "string" && defaultValue) {
50
+ const matched = optionList.find(
51
+ (opt: GenericObject) => opt.label?.toLowerCase() === defaultValue.toLowerCase()
52
+ );
53
+ if (matched?.id != null && matched.id !== "") return String(matched.id);
54
+ }
55
+ return undefined;
56
+ }
57
+ if (multiSelect) {
58
+ const arr = Array.isArray(defaultValue)
59
+ ? defaultValue
60
+ : defaultValue && typeof defaultValue === "object" && Object.keys(defaultValue).length
61
+ ? [defaultValue as GenericObject]
62
+ : [];
63
+ if (!arr.length) return undefined;
64
+ const ids = arr
65
+ .map((v) => optionDefaultId(v as GenericObject))
66
+ .filter((id) => id != null && id !== "");
67
+ return ids.length ? ids.join(",") : undefined;
68
+ }
69
+ if (defaultValue && typeof defaultValue === "object" && !Array.isArray(defaultValue)) {
70
+ const id = optionDefaultId(defaultValue as GenericObject);
71
+ if (id) return id;
72
+ }
73
+ return undefined;
74
+ }
75
+
24
76
  type CustomQuickPickDate = {
25
77
  label: string;
26
78
  value: string[] | { timePeriod: string; amount: number };
@@ -157,6 +209,11 @@ let Dropdown = (props: DropdownProps, ref: any): React.ReactElement | null => {
157
209
  initialSelected
158
210
  );
159
211
 
212
+ const filterResetDefaultSerialized = useMemo(
213
+ () => serializeDropdownFilterResetDefault(variant, multiSelect, defaultValue, dropdownOptions),
214
+ [variant, multiSelect, defaultValue, dropdownOptions]
215
+ );
216
+
160
217
  const [isInputFocused, setIsInputFocused] = useState(false);
161
218
  const [hasTriggerSubcomponent, setHasTriggerSubcomponent] = useState(true);
162
219
  const [hasContainerSubcomponent, setHasContainerSubcomponent] =
@@ -432,6 +489,7 @@ let Dropdown = (props: DropdownProps, ref: any): React.ReactElement | null => {
432
489
  <div {...ariaProps}
433
490
  {...dataProps}
434
491
  {...htmlProps}
492
+ {...(filterResetDefaultSerialized ? { "data-default-value": filterResetDefaultSerialized } : {})}
435
493
  className={classes}
436
494
  id={id}
437
495
  ref={outerDivRef}
@@ -12,7 +12,9 @@
12
12
  <% end %>
13
13
  <div class="dropdown_wrapper<%= error_class %>" style="position: relative">
14
14
  <input
15
+ <% if input_default_value.present? %>
15
16
  data-default-value="<%= input_default_value %>"
17
+ <% end %>
16
18
  data-dropdown-selected-option
17
19
  name="<%= object.name %><%= '[]' if object.multi_select %>"
18
20
  style="display: none"
@@ -51,6 +51,7 @@ test('generated default kit and classname', () => {
51
51
  const kit = screen.getByTestId(testId)
52
52
  expect(kit).toBeInTheDocument()
53
53
  expect(kit).toHaveClass('pb_dropdown_default')
54
+ expect(kit).not.toHaveAttribute('data-default-value')
54
55
  })
55
56
 
56
57
  test('generated default Trigger and Container when none passed in', () => {
@@ -433,12 +434,16 @@ test("defaultValue works with multiSelect", () => {
433
434
  render(
434
435
  <Dropdown
435
436
  data={{ testid: testId }}
436
- defaultValue={[options[0], options[2]]}
437
+ defaultValue={[
438
+ { label: options[0].label, value: options[0].value },
439
+ { label: options[2].label, value: options[2].value },
440
+ ]}
437
441
  multiSelect
438
442
  options={options}
439
443
  />
440
444
  )
441
445
  const kit = screen.getByTestId(testId)
446
+ expect(kit).toHaveAttribute("data-default-value", "United-states,pakistan")
442
447
  expect(kit.querySelectorAll(".pb_form_pill_kit.pb_form_pill_primary")).toHaveLength(2)
443
448
  const option2 = Array.from(kit.querySelectorAll(".pb_dropdown_option_list"));
444
449
  const firstOpt = options[0].label
@@ -499,6 +504,7 @@ test("quickpick variant accepts string defaultValue", () => {
499
504
  const trigger = kit.querySelector('.pb_dropdown_trigger')
500
505
 
501
506
  expect(trigger).toHaveTextContent("This Month")
507
+ expect(kit).toHaveAttribute("data-default-value", "quickpick-this-month")
502
508
  })
503
509
 
504
510
  test("quickpick attaches _dropdownRef to DOM element when id is provided", () => {
@@ -69,10 +69,9 @@ svg {
69
69
  transform: scaleX(-1) scaleY(-1);
70
70
  }
71
71
  &.svg-inline--fa {
72
- box-sizing: content-box;
73
72
  height: 1em;
74
73
  overflow: visible;
75
- vertical-align: -.125em;
74
+ vertical-align: -.125em
76
75
  }
77
76
  &.svg_inverse {
78
77
  color: #fff;
@@ -84,19 +84,6 @@
84
84
  "react",
85
85
  "rails"
86
86
  ]
87
- },
88
- "required": {
89
- "platforms": [
90
- "rails"
91
- ],
92
- "type": "boolean",
93
- "default": false
94
- },
95
- "minLength": {
96
- "platforms": [
97
- "rails"
98
- ],
99
- "type": "number"
100
87
  }
101
88
  },
102
89
  "globalProps": true,
@@ -1,70 +1 @@
1
- <%= pb_content_tag(:div) do %>
2
- <label>
3
- <%= pb_rails("flex", props: { align: "baseline", margin_bottom: show_label? ? "xs" : nil }.compact) do %>
4
- <% if show_label? %>
5
- <% if show_required_indicator? %>
6
- <%= pb_rails("caption", props: { dark: object.dark, classname: "passphrase-label", color: "lighter" }) do %>
7
- <%= object.display_label %> <span class="required_indicator">*</span>
8
- <% end %>
9
- <% else %>
10
- <%= pb_rails("caption", props: {
11
- dark: object.dark,
12
- classname: "passphrase-label",
13
- color: "lighter",
14
- text: object.display_label,
15
- }) %>
16
- <% end %>
17
- <% end %>
18
-
19
- <% if object.show_tips? %>
20
- <%= pb_rails("circle_icon_button", props: {
21
- classname: object.tips_button_class,
22
- dark: object.dark,
23
- icon: "info-circle",
24
- id: object.tips_trigger_id,
25
- variant: "link",
26
- }) %>
27
- <%= pb_rails("popover", props: {
28
- close_on_click: "outside",
29
- position: "right",
30
- trigger_element_id: object.tips_trigger_id,
31
- tooltip_id: object.tips_tooltip_id,
32
- }) do %>
33
- <%= pb_rails("flex", props: { align: "center", orientation: "column" }) do %>
34
- <%= pb_rails("caption", props: {
35
- color: "lighter",
36
- margin_bottom: "xs",
37
- text: "Tips for a good passphrase",
38
- }) %>
39
- <div>
40
- <% object.tips.each do |tip| %>
41
- <%= pb_rails("flex", props: { align: "center", margin_bottom: "xs" }) do %>
42
- <%= pb_rails("icon", props: { icon: "shield-check", margin_right: "xs" }) %>
43
- <%= pb_rails("caption", props: { color: "lighter", size: "xs", text: tip }) %>
44
- <% end %>
45
- <% end %>
46
- </div>
47
- <% end %>
48
- <% end %>
49
- <% end %>
50
- <% end %>
51
-
52
- <div class="passphrase-text-input-wrapper">
53
- <%= pb_rails("text_input", props: object.text_input_props) %>
54
- <span
55
- aria-label="Passphrase currently hidden. Click icon to reveal password"
56
- aria-pressed="false"
57
- class="show-passphrase-icon"
58
- role="button"
59
- tabindex="0"
60
- >
61
- <%= pb_rails("body", props: { classname: "passphrase-toggle-icon", color: "light", dark: object.dark }) do %>
62
- <%= pb_rails("icon", props: { aria: { label: "eye icon" }, icon: "eye-slash" }) %>
63
- <% end %>
64
- <%= pb_rails("body", props: { classname: "passphrase-toggle-icon hide-icon", color: "light", dark: object.dark }) do %>
65
- <%= pb_rails("icon", props: { aria: { label: "eye icon" }, icon: "eye" }) %>
66
- <% end %>
67
- </span>
68
- </div>
69
- </label>
70
- <% end %>
1
+ <%= react_component('Passphrase', object.passphrase_options, class: object.classname, **combined_html_options) %>
@@ -11,69 +11,12 @@ module Playbook
11
11
  default: "always"
12
12
  prop :tips, type: Playbook::Props::Array, default: []
13
13
  prop :required_indicator, type: Playbook::Props::Boolean, default: false
14
- prop :required, type: Playbook::Props::Boolean, default: false
15
- prop :min_length, type: Playbook::Props::Number
16
14
  prop :value, type: Playbook::Props::String
17
15
 
18
16
  def classname
19
17
  generate_classname("pb_passphrase")
20
18
  end
21
19
 
22
- def data
23
- Hash(values[:data]).merge(pb_passphrase: true)
24
- end
25
-
26
- def display_label
27
- return label if label.present?
28
- return "Confirm Passphrase" if confirmation
29
-
30
- "Passphrase"
31
- end
32
-
33
- def show_label?
34
- display_label.present?
35
- end
36
-
37
- def show_required_indicator?
38
- required_indicator || required
39
- end
40
-
41
- def show_tips?
42
- tips.present? && !confirmation
43
- end
44
-
45
- def tips_trigger_id
46
- @tips_trigger_id ||= "passphrase-tips-trigger-#{dom_id_suffix}"
47
- end
48
-
49
- def tips_tooltip_id
50
- @tips_tooltip_id ||= "passphrase-tips-tooltip-#{dom_id_suffix}"
51
- end
52
-
53
- def tips_button_class
54
- classes = %w[passphrase-popover passphrase-tips]
55
- classes << "show-below-#{show_tips_below}" unless show_tips_below == "always"
56
- classes.join(" ")
57
- end
58
-
59
- def text_input_props
60
- {
61
- dark: dark,
62
- data: text_input_data,
63
- margin_bottom: "none",
64
- classname: "passphrase-text-input",
65
- placeholder: "Enter a passphrase...",
66
- required: required,
67
- type: "password",
68
- value: value,
69
- input_options: merged_input_options,
70
- }.compact
71
- end
72
-
73
- def text_input_data
74
- input_props.with_indifferent_access.fetch(:data, {}).to_h
75
- end
76
-
77
20
  def passphrase_options
78
21
  {
79
22
  dark: dark,
@@ -88,19 +31,6 @@ module Playbook
88
31
  value: value,
89
32
  }.compact
90
33
  end
91
-
92
- private
93
-
94
- def dom_id_suffix
95
- id.presence || object_id
96
- end
97
-
98
- def merged_input_options
99
- options = input_props.deep_dup.with_indifferent_access.except(:data)
100
- options[:class] = [options[:class], options.delete(:classname)].compact.join(" ").strip.presence
101
- options[:minlength] = min_length if min_length.present?
102
- options
103
- end
104
34
  end
105
35
  end
106
36
  end
@@ -50,9 +50,18 @@ module Playbook
50
50
  def validation_data
51
51
  fields = input_options[:data] || {}
52
52
  fields[:message] = validation_message unless validation_message.blank?
53
+ dv = filter_reset_default_value
54
+ fields[:default_value] = dv if dv.present?
53
55
  fields
54
56
  end
55
57
 
58
+ def filter_reset_default_value
59
+ s = selected
60
+ return if s.blank?
61
+
62
+ s.join(",")
63
+ end
64
+
56
65
  # Same resolved id as the native +<select>+ (+all_attributes[:id]+) for label +for+.
57
66
  def select_input_id
58
67
  all_attributes[:id].presence