playbook_ui 13.31.0.pre.alpha.powercentrainplaybookpt23212 → 13.32.0.pre.alpha.PBNTR405dropdownformfixesrails3301

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 (107) hide show
  1. checksums.yaml +4 -4
  2. data/app/pb_kits/playbook/pb_background/background.html.erb +11 -2
  3. data/app/pb_kits/playbook/pb_bar_graph/docs/_bar_graph_custom.md +4 -0
  4. data/app/pb_kits/playbook/pb_body/body.html.erb +6 -1
  5. data/app/pb_kits/playbook/pb_bread_crumbs/bread_crumb_item.html.erb +6 -1
  6. data/app/pb_kits/playbook/pb_bread_crumbs/bread_crumbs.html.erb +6 -1
  7. data/app/pb_kits/playbook/pb_caption/caption.html.erb +6 -1
  8. data/app/pb_kits/playbook/pb_card/card.html.erb +7 -1
  9. data/app/pb_kits/playbook/pb_collapsible/__snapshots__/collapsible.test.js.snap +1 -1
  10. data/app/pb_kits/playbook/pb_detail/detail.html.erb +6 -1
  11. data/app/pb_kits/playbook/pb_dialog/dialog.html.erb +6 -1
  12. data/app/pb_kits/playbook/pb_dialog/dialog_body.html.erb +6 -1
  13. data/app/pb_kits/playbook/pb_dialog/dialog_footer.html.erb +5 -2
  14. data/app/pb_kits/playbook/pb_dialog/dialog_header.html.erb +6 -1
  15. data/app/pb_kits/playbook/pb_dropdown/_dropdown.tsx +12 -7
  16. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_blank_selection.html.erb +10 -0
  17. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_blank_selection.jsx +31 -0
  18. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_default_value.html.erb +10 -0
  19. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_default_value.jsx +31 -0
  20. data/app/pb_kits/playbook/pb_dropdown/docs/example.yml +4 -0
  21. data/app/pb_kits/playbook/pb_dropdown/docs/index.js +3 -1
  22. data/app/pb_kits/playbook/pb_dropdown/dropdown.html.erb +3 -4
  23. data/app/pb_kits/playbook/pb_dropdown/dropdown.rb +11 -0
  24. data/app/pb_kits/playbook/pb_dropdown/dropdown_trigger.rb +1 -1
  25. data/app/pb_kits/playbook/pb_dropdown/index.js +75 -17
  26. data/app/pb_kits/playbook/pb_flex/flex.html.erb +5 -1
  27. data/app/pb_kits/playbook/pb_form_pill/_form_pill.scss +108 -5
  28. data/app/pb_kits/playbook/pb_form_pill/_form_pill.test.jsx +53 -0
  29. data/app/pb_kits/playbook/pb_form_pill/_form_pill.tsx +11 -2
  30. data/app/pb_kits/playbook/pb_form_pill/docs/_form_pill_example.html.erb +5 -1
  31. data/app/pb_kits/playbook/pb_form_pill/docs/_form_pill_example.jsx +1 -0
  32. data/app/pb_kits/playbook/pb_form_pill/docs/_form_pill_size.html.erb +2 -0
  33. data/app/pb_kits/playbook/pb_form_pill/docs/_form_pill_size.jsx +2 -0
  34. data/app/pb_kits/playbook/pb_form_pill/docs/_form_pill_tag.html.erb +4 -1
  35. data/app/pb_kits/playbook/pb_form_pill/docs/_form_pill_tag.jsx +3 -2
  36. data/app/pb_kits/playbook/pb_form_pill/docs/_form_pill_user.html.erb +2 -0
  37. data/app/pb_kits/playbook/pb_form_pill/docs/_form_pill_user.jsx +2 -0
  38. data/app/pb_kits/playbook/pb_form_pill/form_pill.html.erb +1 -1
  39. data/app/pb_kits/playbook/pb_form_pill/form_pill.rb +5 -1
  40. data/app/pb_kits/playbook/pb_hashtag/hashtag.html.erb +6 -1
  41. data/app/pb_kits/playbook/pb_highlight/highlight.html.erb +5 -1
  42. data/app/pb_kits/playbook/pb_home_address_street/home_address_street.html.erb +5 -1
  43. data/app/pb_kits/playbook/pb_icon/_icon.scss +210 -1
  44. data/app/pb_kits/playbook/pb_icon/_icon.tsx +100 -41
  45. data/app/pb_kits/playbook/pb_icon/icon.rb +33 -19
  46. data/app/pb_kits/playbook/pb_nav/_nav_item.test.js +2 -2
  47. data/app/pb_kits/playbook/pb_nav/docs/_tab_nav.html.erb +48 -0
  48. data/app/pb_kits/playbook/pb_nav/docs/_tab_nav.md +3 -0
  49. data/app/pb_kits/playbook/pb_nav/docs/example.yml +1 -0
  50. data/app/pb_kits/playbook/pb_nav/index.js +43 -0
  51. data/app/pb_kits/playbook/pb_nav/nav.rb +9 -0
  52. data/app/pb_kits/playbook/pb_rich_text_editor/TipTap/MoreExtensionsDropdown.tsx +1 -1
  53. data/app/pb_kits/playbook/pb_rich_text_editor/TipTap/ToolbarDropdown.tsx +1 -1
  54. data/app/pb_kits/playbook/pb_star_rating/_star_rating.scss +11 -2
  55. data/app/pb_kits/playbook/pb_star_rating/docs/_star_rating_interactive.html.erb +1 -0
  56. data/app/pb_kits/playbook/pb_star_rating/docs/example.yml +1 -1
  57. data/app/pb_kits/playbook/pb_star_rating/index.js +50 -0
  58. data/app/pb_kits/playbook/pb_star_rating/star_rating.html.erb +25 -5
  59. data/app/pb_kits/playbook/pb_star_rating/star_rating.rb +6 -0
  60. data/app/pb_kits/playbook/pb_table/_table.tsx +1 -1
  61. data/app/pb_kits/playbook/pb_table/index.ts +4 -4
  62. data/app/pb_kits/playbook/pb_table/subcomponents/_table_body.tsx +1 -1
  63. data/app/pb_kits/playbook/pb_table/subcomponents/_table_cell.tsx +1 -1
  64. data/app/pb_kits/playbook/pb_table/subcomponents/_table_head.tsx +1 -1
  65. data/app/pb_kits/playbook/pb_table/subcomponents/_table_header.tsx +1 -1
  66. data/app/pb_kits/playbook/pb_table/subcomponents/_table_row.tsx +1 -1
  67. data/app/pb_kits/playbook/pb_table/table.test.js +2 -0
  68. data/app/pb_kits/playbook/pb_text_input/_text_input.tsx +1 -1
  69. data/app/pb_kits/playbook/pb_text_input/docs/_text_input_default.jsx +1 -1
  70. data/app/pb_kits/playbook/pb_textarea/_textarea.tsx +45 -27
  71. data/app/pb_kits/playbook/pb_textarea/index.tsx +3 -3
  72. data/app/pb_kits/playbook/pb_time/_time.tsx +3 -3
  73. data/app/pb_kits/playbook/pb_time_range_inline/_time_range_inline.tsx +1 -1
  74. data/app/pb_kits/playbook/pb_timeline/_item.tsx +1 -1
  75. data/app/pb_kits/playbook/pb_timeline/_timeline.tsx +1 -1
  76. data/app/pb_kits/playbook/pb_title_detail/_title_detail.tsx +10 -10
  77. data/app/pb_kits/playbook/pb_toggle/_toggle.tsx +1 -1
  78. data/app/pb_kits/playbook/pb_tooltip/_tooltip.tsx +2 -2
  79. data/app/pb_kits/playbook/pb_treemap_chart/_treemap_chart.tsx +1 -2
  80. data/app/pb_kits/playbook/pb_treemap_chart/treemapChart.test.js +2 -0
  81. data/app/pb_kits/playbook/pb_typeahead/_typeahead.tsx +3 -3
  82. data/app/pb_kits/playbook/pb_typeahead/components/ClearIndicator.tsx +4 -4
  83. data/app/pb_kits/playbook/pb_typeahead/components/Control.tsx +11 -7
  84. data/app/pb_kits/playbook/pb_typeahead/components/IndicatorsContainer.tsx +8 -3
  85. data/app/pb_kits/playbook/pb_typeahead/components/MenuList.tsx +6 -1
  86. data/app/pb_kits/playbook/pb_typeahead/components/MultiValue.tsx +18 -19
  87. data/app/pb_kits/playbook/pb_typeahead/components/Option.tsx +6 -6
  88. data/app/pb_kits/playbook/pb_typeahead/components/Placeholder.tsx +6 -6
  89. data/app/pb_kits/playbook/pb_typeahead/components/ValueContainer.tsx +3 -3
  90. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_custom_menu_list.jsx +2 -0
  91. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_default.html.erb +22 -57
  92. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_with_pills_async.jsx +2 -2
  93. data/app/pb_kits/playbook/pb_typeahead/index.ts +31 -31
  94. data/app/pb_kits/playbook/pb_user/_user.tsx +1 -1
  95. data/app/pb_kits/playbook/pb_user_badge/_user_badge.tsx +6 -6
  96. data/app/pb_kits/playbook/pb_user_badge/badges/million-dollar.tsx +236 -235
  97. data/app/pb_kits/playbook/pb_user_badge/badges/veteran.tsx +1 -1
  98. data/app/pb_kits/playbook/pb_walkthrough/_walkthrough.tsx +68 -63
  99. data/app/pb_kits/playbook/pb_weekday_stacked/_weekday_stacked.tsx +2 -2
  100. data/app/pb_kits/playbook/playbook-rails.js +6 -0
  101. data/dist/menu.yml +1 -1
  102. data/dist/playbook-rails.js +7 -7
  103. data/lib/playbook/forms/builder/star_rating_field.rb +14 -0
  104. data/lib/playbook/forms/builder.rb +1 -0
  105. data/lib/playbook/version.rb +2 -2
  106. metadata +13 -3
  107. data/app/pb_kits/playbook/pb_icon/icon_aliases.json +0 -39
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4a1c64dce06929e6d1c5308db0a219c98928f941b659f06d2a6780d8ec7884de
4
- data.tar.gz: 2f5256ff5648697c7f144b54dc62277e23c1189d1c0ae87d04c60f86a1fe7240
3
+ metadata.gz: 46be62680a9b7f69c65dbc7401bac4bfa0fdcc6eb8e77b636053147335db6aeb
4
+ data.tar.gz: a6b937a47504236820e0452a347643dd726ab61d2b95ecf78ecaf9c88eae14cf
5
5
  SHA512:
6
- metadata.gz: f06bcdc6d07585a0eb44a4784f32cf9d1bccfc4e8811dee814e6affa7c587983d32615663745b14ab37f3e542ecb0aa0e159aa36fc5b75c4032ffcdfbcddd3fc
7
- data.tar.gz: cea9826880aad795f72f212dd9719800dee0de2c09fb090c6f2c3bfd7f1624c0f1b615ede15c0cf444c25df80e429cfeb416fb665752924cb9095655a5040ac3
6
+ metadata.gz: 30558fa14a011d3a22c55218a8e66e23a6beb66f11e065135189e5f171799669c7f213aa751554df57dc599416b99759971f66d319e9c44a4cdd30dfb23c25d7
7
+ data.tar.gz: 5690e376f3790d415dc66f95a53c73327fd5c5f769ed7dd3199aa097ca1f36c3584505bffa08ae142d546f5249c199160f531772e904878f06c89d9d7fabcdc6
@@ -1,14 +1,23 @@
1
1
  <% if object.image_url.present? %>
2
- <%= pb_content_tag(object.tag,
2
+ <%= content_tag(object.tag,
3
+ aria: object.aria,
4
+ data: object.data,
5
+ id: object.id,
6
+ class: object.classname,
3
7
  style: "background-image: url('#{object.image_url}');
4
8
  background-repeat: #{object.background_repeat};
5
9
  background-size: #{object.background_size};
6
10
  background-position: #{object.background_position};",
11
+ **combined_html_options
7
12
  ) do %>
8
13
  <%= content.presence %>
9
14
  <% end %>
10
15
  <% else %>
11
- <%= pb_content_tag(object.tag,
16
+ <%= content_tag(object.tag,
17
+ aria: object.aria,
18
+ data: object.data,
19
+ id: object.id,
20
+ class: object.classname,
12
21
  style: object.custom_background_color
13
22
  ) do %>
14
23
  <%= content.presence %>
@@ -1,2 +1,6 @@
1
1
  The `customOptions` prop provides comprehensive access to additional [Highcharts options](https://api.highcharts.com/highcharts/) that are not explicitly defined as props.
2
2
  It's important to note that certain options may require specific script imports to function properly.
3
+
4
+ Note: If you are having trouble getting any Highcharts options to work, please match the formatting of our [staticOptions](https://github.com/powerhome/playbook/blob/master/playbook/app/pb_kits/playbook/pb_bar_graph/_bar_graph.tsx#L85-L141). For example, `yAxis` will need to be wrapped with square brackets.
5
+
6
+ You may also need to override any of the [defaults](https://github.com/powerhome/playbook/blob/master/playbook/app/pb_kits/playbook/pb_bar_graph/_bar_graph.tsx#L45-L73) in order to get that options to work.
@@ -1,3 +1,8 @@
1
- <%= pb_content_tag(object.tag) do %>
1
+ <%= content_tag(object.tag,
2
+ aria: object.aria,
3
+ id: object.id,
4
+ data: object.data,
5
+ class: object.classname,
6
+ **combined_html_options) do %>
2
7
  <%= object.content %>
3
8
  <% end %>
@@ -1,4 +1,9 @@
1
- <%= pb_content_tag do%>
1
+ <%= content_tag(:div,
2
+ id: object.id,
3
+ data: object.data,
4
+ class: object.classname,
5
+ aria: object.aria,
6
+ **combined_html_options) do%>
2
7
  <%= content_tag(object.link ? 'a' : 'span', class: 'bread_crumb_item', href: object.link) do %>
3
8
  <%= content.presence %>
4
9
  <% end %>
@@ -1,3 +1,8 @@
1
- <%= pb_content_tag(:nav) do %>
1
+ <%= content_tag(:nav,
2
+ aria: object.aria,
3
+ id: object.id,
4
+ data: object.data,
5
+ class: object.classname,
6
+ **combined_html_options) do %>
2
7
  <%= content.presence %>
3
8
  <% end %>
@@ -1,3 +1,8 @@
1
- <%= pb_content_tag(object.tag) do %>
1
+ <%= content_tag(object.tag,
2
+ aria: object.aria,
3
+ id: object.id,
4
+ data: object.data,
5
+ class: object.classname,
6
+ **combined_html_options) do %>
2
7
  <%= content.presence || object.text %>
3
8
  <% end %>
@@ -1,4 +1,10 @@
1
- <%= pb_content_tag(object.tag) do %>
1
+ <%= content_tag(object.tag,
2
+ id: object.id,
3
+ data: object.data,
4
+ class: object.classname,
5
+ aria: object.aria,
6
+ dark: object.dark,
7
+ **combined_html_options) do %>
2
8
  <%= content.presence %>
3
9
  <% end %>
4
10
 
@@ -28,7 +28,7 @@ exports[`html structure is correct 1`] = `
28
28
  style="vertical-align: middle; color: rgb(193, 205, 214);"
29
29
  >
30
30
  <i
31
- class="pb_icon_kit far fa-fw fa-lg fa-chevron-down"
31
+ class="pb_icon_kit far fa-lg fa-fw fa-lg fa-chevron-down"
32
32
  />
33
33
  <span
34
34
  aria-label="chevron-down icon"
@@ -1,3 +1,8 @@
1
- <%= pb_content_tag(object.tag) do %>
1
+ <%= content_tag(object.tag,
2
+ aria: object.aria,
3
+ class: object.classname,
4
+ data: object.data,
5
+ id: object.id,
6
+ **combined_html_options) do %>
2
7
  <%= object.content %>
3
8
  <% end %>
@@ -1,5 +1,10 @@
1
1
  <div class="pb_dialog_wrapper_rails <%= object.full_height_style %>" data-overlay-click= <%= object.overlay_close %> >
2
- <%= pb_content_tag(:dialog) do %>
2
+ <%= content_tag(:dialog,
3
+ aria: object.aria,
4
+ data: object.data,
5
+ id: object.id,
6
+ class: object.classname,
7
+ **combined_html_options) do %>
3
8
  <% if object.status === "" && object.title %>
4
9
  <%= pb_rails("dialog/dialog_header", props: { title: object.title, id: object.id }) %>
5
10
  <% end %>
@@ -1,3 +1,8 @@
1
- <%= pb_content_tag do %>
1
+ <%= content_tag(:div,
2
+ id: object.id,
3
+ data: object.data,
4
+ class: object.classname,
5
+ aria: object.aria,
6
+ **combined_html_options) do %>
2
7
  <%= content.presence || object.text %>
3
8
  <% end %>
@@ -1,5 +1,8 @@
1
- <%= pb_content_tag(:div, class: "") do %>
2
- <% 'excluded classname?' %>
1
+ <%= content_tag(:div,
2
+ id: object.id,
3
+ data: object.data,
4
+ aria: object.aria,
5
+ **combined_html_options) do %>
3
6
  <% if object.confirm_button && object.cancel_button %>
4
7
  <div class="dialog-pseudo-footer"></div>
5
8
  <%= pb_rails("flex", props: { classname:object.classname, spacing:"between", padding_x:"sm", padding:"sm", padding_bottom:"sm" }) do %>
@@ -1,4 +1,9 @@
1
- <%= pb_content_tag(:div, class: object.sticky_header) do %>
1
+ <%= content_tag(:div,
2
+ id: object.id,
3
+ data: object.data,
4
+ class: object.sticky_header,
5
+ aria: object.aria,
6
+ **combined_html_options) do %>
2
7
  <%= pb_rails("flex", props: {classname:object.classname, spacing:"between", padding:"sm", align:"center"}) do %>
3
8
  <%= content.presence || object.title %>
4
9
 
@@ -22,10 +22,12 @@ import {
22
22
  type DropdownProps = {
23
23
  aria?: { [key: string]: string };
24
24
  autocomplete?: boolean;
25
+ blankSelection?: string;
25
26
  children?: React.ReactChild[] | React.ReactChild | React.ReactElement[];
26
27
  className?: string;
27
28
  dark?: boolean;
28
29
  data?: { [key: string]: string };
30
+ defaultValue?: GenericObject;
29
31
  error?: string;
30
32
  htmlOptions?: { [key: string]: string | number | boolean | (() => void) },
31
33
  id?: string;
@@ -40,10 +42,12 @@ const Dropdown = (props: DropdownProps) => {
40
42
  const {
41
43
  aria = {},
42
44
  autocomplete = false,
45
+ blankSelection = '',
43
46
  children,
44
47
  className,
45
48
  dark = false,
46
49
  data = {},
50
+ defaultValue = {},
47
51
  error,
48
52
  htmlOptions = {},
49
53
  id,
@@ -66,7 +70,7 @@ const Dropdown = (props: DropdownProps) => {
66
70
  const [isDropDownClosed, setIsDropDownClosed, toggleDropdown] = useDropdown(isClosed);
67
71
 
68
72
  const [filterItem, setFilterItem] = useState("");
69
- const [selected, setSelected] = useState<GenericObject>({});
73
+ const [selected, setSelected] = useState<GenericObject>(defaultValue);
70
74
  const [isInputFocused, setIsInputFocused] = useState(false);
71
75
  const [hasTriggerSubcomponent, setHasTriggerSubcomponent] = useState(true);
72
76
  const [hasContainerSubcomponent, setHasContainerSubcomponent] =
@@ -116,11 +120,12 @@ const Dropdown = (props: DropdownProps) => {
116
120
  setIsDropDownClosed(isClosed)
117
121
  }, [isClosed])
118
122
 
119
- const filteredOptions = options?.filter((option: GenericObject) => {
123
+ const blankSelectionOption: GenericObject = blankSelection ? [{ label: blankSelection, value: "" }] : [];
124
+ const optionsWithBlankSelection = blankSelectionOption.concat(options);
125
+ const filteredOptions = optionsWithBlankSelection?.filter((option: GenericObject) => {
120
126
  const label = typeof option.label === 'string' ? option.label.toLowerCase() : option.label;
121
127
  return String(label).toLowerCase().includes(filterItem.toLowerCase());
122
- }
123
- );
128
+ });
124
129
 
125
130
  // For keyboard accessibility: Set focus within dropdown to selected item if it exists
126
131
  useEffect(() => {
@@ -194,7 +199,7 @@ const Dropdown = (props: DropdownProps) => {
194
199
  inputWrapperRef,
195
200
  isDropDownClosed,
196
201
  isInputFocused,
197
- options,
202
+ optionsWithBlankSelection,
198
203
  selected,
199
204
  setFocusedOptionIndex,
200
205
  setIsDropDownClosed,
@@ -233,8 +238,8 @@ const Dropdown = (props: DropdownProps) => {
233
238
  <>
234
239
  <DropdownTrigger />
235
240
  <DropdownContainer>
236
- {options &&
237
- options?.map((option: GenericObject) => (
241
+ {optionsWithBlankSelection &&
242
+ optionsWithBlankSelection?.map((option: GenericObject) => (
238
243
  <Dropdown.Option key={option.id}
239
244
  option={option}
240
245
  />
@@ -0,0 +1,10 @@
1
+ <%
2
+ options = [
3
+ { label: 'United States', value: 'United States', id: 'us' },
4
+ { label: 'Canada', value: 'Canada', id: 'ca' },
5
+ { label: 'Pakistan', value: 'Pakistan', id: 'pk' },
6
+ ]
7
+
8
+ %>
9
+
10
+ <%= pb_rails("dropdown", props: { blank_selection: "Select One...", options: options }) %>
@@ -0,0 +1,31 @@
1
+ import React from 'react'
2
+ import { Dropdown } from '../../'
3
+
4
+ const DropdownBlankSelection = (props) => {
5
+ const options = [
6
+ {
7
+ label: "United States",
8
+ value: "United States",
9
+ },
10
+ {
11
+ label: "Canada",
12
+ value: "Canada",
13
+ },
14
+ {
15
+ label: "Pakistan",
16
+ value: "Pakistan",
17
+ }
18
+ ];
19
+
20
+ return (
21
+ <>
22
+ <Dropdown
23
+ blankSelection="Select one..."
24
+ options={options}
25
+ {...props}
26
+ />
27
+ </>
28
+ )
29
+ }
30
+
31
+ export default DropdownBlankSelection
@@ -0,0 +1,10 @@
1
+ <%
2
+ options = [
3
+ { label: 'United States', value: 'United States', id: 'us' },
4
+ { label: 'Canada', value: 'Canada', id: 'ca' },
5
+ { label: 'Pakistan', value: 'Pakistan', id: 'pk' },
6
+ ]
7
+
8
+ %>
9
+
10
+ <%= pb_rails("dropdown", props: {options: options, default_value: options.last}) %>
@@ -0,0 +1,31 @@
1
+ import React from 'react'
2
+ import { Dropdown } from '../../'
3
+
4
+ const DropdownDefaultValue = (props) => {
5
+ const options = [
6
+ {
7
+ label: "United States",
8
+ value: "United States",
9
+ },
10
+ {
11
+ label: "Canada",
12
+ value: "Canada",
13
+ },
14
+ {
15
+ label: "Pakistan",
16
+ value: "Pakistan",
17
+ }
18
+ ];
19
+
20
+ return (
21
+ <>
22
+ <Dropdown
23
+ defaultValue={options[2]}
24
+ options={options}
25
+ {...props}
26
+ />
27
+ </>
28
+ )
29
+ }
30
+
31
+ export default DropdownDefaultValue
@@ -8,6 +8,8 @@ examples:
8
8
  - dropdown_with_custom_trigger_rails: Custom Trigger
9
9
  - dropdown_with_custom_padding: Custom Option Padding
10
10
  - dropdown_error: Dropdown with Error
11
+ - dropdown_default_value: Default Value
12
+ - dropdown_blank_selection: Blank Selection
11
13
 
12
14
  react:
13
15
  - dropdown_default: Default
@@ -18,6 +20,8 @@ examples:
18
20
  - dropdown_with_custom_trigger: Custom Trigger
19
21
  - dropdown_with_custom_padding: Custom Option Padding
20
22
  - dropdown_error: Dropdown with Error
23
+ - dropdown_default_value: Default Value
24
+ - dropdown_blank_selection: Blank Selection
21
25
  # - dropdown_with_autocomplete: Autocomplete
22
26
  # - dropdown_with_autocomplete_and_custom_display: Autocomplete with Custom Display
23
27
  # - dropdown_with_external_control: useDropdown Hook
@@ -9,4 +9,6 @@ export { default as DropdownWithLabel } from './_dropdown_with_label.jsx'
9
9
  export { default as DropdownWithExternalControl } from './_dropdown_with_external_control.jsx'
10
10
  export { default as DropdownWithHook } from './_dropdown_with_hook.jsx'
11
11
  export { default as DropdownSubcomponentStructure } from './_dropdown_subcomponent_structure.jsx'
12
- export { default as DropdownError } from './_dropdown_error.jsx'
12
+ export { default as DropdownError } from './_dropdown_error.jsx'
13
+ export { default as DropdownDefaultValue } from './_dropdown_default_value.jsx'
14
+ export { default as DropdownBlankSelection } from './_dropdown_blank_selection.jsx'
@@ -8,8 +8,7 @@
8
8
  <%= pb_rails("caption", props: {text: object.label, margin_bottom:"xs"}) %>
9
9
  <% end %>
10
10
  <div class="dropdown_wrapper<%= error_class %>" style="position: relative">
11
- <input type="hidden" name="<%= object.name %>" id="dropdown-selected-option" value="" />
12
- <input id="dropdown-form-validation" name="<%= object.name %>_form_validation" value="" style="display: none" <%= object.required ? "required" : ""%> />
11
+ <input id="dropdown-selected-option" name="<%= object.name %>" value="<%= input_default_value %>" style="display: none" <%= object.required ? "required" : ""%> />
13
12
 
14
13
  <% if content.present? %>
15
14
  <%= content.presence %>
@@ -17,8 +16,8 @@
17
16
  <% else %>
18
17
  <%= pb_rails("dropdown/dropdown_trigger") %>
19
18
  <%= pb_rails("dropdown/dropdown_container") do %>
20
- <% if object.options.present? %>
21
- <% object.options.each do |option| %>
19
+ <% if options_with_blank.present? %>
20
+ <% options_with_blank.each do |option| %>
22
21
  <%= pb_rails("dropdown/dropdown_option", props: {option: option}) %>
23
22
  <% end %>
24
23
  <% end %>
@@ -10,6 +10,9 @@ module Playbook
10
10
  prop :error, type: Playbook::Props::String
11
11
  prop :required, type: Playbook::Props::Boolean,
12
12
  default: false
13
+ prop :default_value
14
+ prop :blank_selection, type: Playbook::Props::String,
15
+ default: ""
13
16
 
14
17
  def data
15
18
  Hash(prop(:data)).merge(pb_dropdown: true)
@@ -24,6 +27,14 @@ module Playbook
24
27
  def error_class
25
28
  error.present? ? " error" : ""
26
29
  end
30
+
31
+ def input_default_value
32
+ default_value.present? ? default_value.transform_keys(&:to_s) : ""
33
+ end
34
+
35
+ def options_with_blank
36
+ blank_selection.present? ? [{ id: "", value: "", label: blank_selection }] + options : options
37
+ end
27
38
  end
28
39
  end
29
40
  end
@@ -11,7 +11,7 @@ module Playbook
11
11
  prop :custom_display
12
12
 
13
13
  def data
14
- Hash(prop(:data)).merge(dropdown_trigger: true)
14
+ Hash(prop(:data)).merge(dropdown_trigger: true, dropdown_placeholder: default_display_placeholder)
15
15
  end
16
16
 
17
17
  def classname
@@ -8,7 +8,9 @@ const DOWN_ARROW_SELECTOR = "#dropdown_open_icon";
8
8
  const UP_ARROW_SELECTOR = "#dropdown_close_icon";
9
9
  const OPTION_SELECTOR = "[data-dropdown-option-label]";
10
10
  const CUSTOM_DISPLAY_SELECTOR = "[data-dropdown-custom-trigger]";
11
- const INPUT_FORM_VALIDATION = "#dropdown-form-validation";
11
+ const DROPDOWN_TRIGGER_DISPLAY = "#dropdown_trigger_display";
12
+ const DROPDOWN_PLACEHOLDER = "[data-dropdown-placeholder]";
13
+ const DROPDOWN_INPUT = "#dropdown-selected-option";
12
14
 
13
15
  export default class PbDropdown extends PbEnhancedElement {
14
16
  static get selector() {
@@ -21,9 +23,11 @@ export default class PbDropdown extends PbEnhancedElement {
21
23
 
22
24
  connect() {
23
25
  this.keyboardHandler = new PbDropdownKeyboard(this);
26
+ this.setDefaultValue();
24
27
  this.bindEventListeners();
25
28
  this.updateArrowDisplay(false);
26
29
  this.handleFormValidation();
30
+ this.handleFormReset();
27
31
  }
28
32
 
29
33
  bindEventListeners() {
@@ -43,14 +47,13 @@ export default class PbDropdown extends PbEnhancedElement {
43
47
 
44
48
  handleOptionClick(event) {
45
49
  const option = event.target.closest(OPTION_SELECTOR);
46
- const hiddenInput = this.element.querySelector("#dropdown-selected-option");
47
- const inputFormValidation = this.element.querySelector(INPUT_FORM_VALIDATION);
50
+ const hiddenInput = this.element.querySelector(DROPDOWN_INPUT);
48
51
 
49
52
  if (option) {
50
53
  const value = option.dataset.dropdownOptionLabel;
51
54
  hiddenInput.value = JSON.parse(value).id;
52
- inputFormValidation.value = JSON.parse(value).id;
53
- this.clearFormValidation(inputFormValidation);
55
+ this.clearFormValidation(hiddenInput);
56
+
54
57
  this.onOptionSelected(value, option);
55
58
  }
56
59
  }
@@ -83,9 +86,7 @@ export default class PbDropdown extends PbEnhancedElement {
83
86
  }
84
87
 
85
88
  onOptionSelected(value, selectedOption) {
86
- const triggerElement = this.element.querySelector(
87
- "#dropdown_trigger_display"
88
- );
89
+ const triggerElement = this.element.querySelector(DROPDOWN_TRIGGER_DISPLAY);
89
90
  const customDisplayElement = this.element.querySelector(
90
91
  "#dropdown_trigger_custom_display"
91
92
  );
@@ -158,14 +159,18 @@ export default class PbDropdown extends PbEnhancedElement {
158
159
  }
159
160
 
160
161
  handleFormValidation() {
161
- const inputFormValidation = this.element.querySelector(INPUT_FORM_VALIDATION);
162
-
163
- inputFormValidation.addEventListener("invalid", function (event) {
164
- if (inputFormValidation.hasAttribute("required") && inputFormValidation.value === "") {
165
- event.preventDefault();
166
- inputFormValidation.closest(".dropdown_wrapper").classList.add("error");
167
- }
168
- }, true);
162
+ const hiddenInput = this.element.querySelector(DROPDOWN_INPUT);
163
+
164
+ hiddenInput.addEventListener(
165
+ "invalid",
166
+ function (event) {
167
+ if (hiddenInput.hasAttribute("required") && hiddenInput.value === "") {
168
+ event.preventDefault();
169
+ hiddenInput.closest(".dropdown_wrapper").classList.add("error");
170
+ }
171
+ },
172
+ true
173
+ );
169
174
  }
170
175
 
171
176
  clearFormValidation(input) {
@@ -173,10 +178,63 @@ export default class PbDropdown extends PbEnhancedElement {
173
178
  const dropdownWrapperElement = input.closest(".dropdown_wrapper");
174
179
  dropdownWrapperElement.classList.remove("error");
175
180
 
176
- const errorLabelElement = dropdownWrapperElement.querySelector(".pb_body_kit_negative");
181
+ const errorLabelElement = dropdownWrapperElement.querySelector(
182
+ ".pb_body_kit_negative"
183
+ );
177
184
  if (errorLabelElement) {
178
185
  errorLabelElement.remove();
179
186
  }
180
187
  }
181
188
  }
189
+
190
+ setDefaultValue() {
191
+ const hiddenInput = this.element.querySelector(DROPDOWN_INPUT);
192
+
193
+ if (hiddenInput.value) {
194
+ const defaultValue = JSON.parse(hiddenInput.value.replaceAll("=>", ":"));
195
+ const options = this.element.querySelectorAll(OPTION_SELECTOR);
196
+
197
+ options.forEach((option) => {
198
+ if (
199
+ defaultValue.id === JSON.parse(option.dataset.dropdownOptionLabel).id
200
+ ) {
201
+ option.classList.add("pb_dropdown_option_selected");
202
+ }
203
+ });
204
+
205
+ this.setTriggerElementText(defaultValue.label);
206
+
207
+ hiddenInput.value = defaultValue.id;
208
+ }
209
+ }
210
+
211
+ handleFormReset() {
212
+ const form = this.element.closest("form");
213
+
214
+ if (form) {
215
+ form.addEventListener("reset", () => {
216
+ this.resetDropdownValue();
217
+ });
218
+ }
219
+ }
220
+
221
+ resetDropdownValue() {
222
+ const hiddenInput = this.element.querySelector(DROPDOWN_INPUT);
223
+ const options = this.element.querySelectorAll(OPTION_SELECTOR);
224
+ options.forEach((option) => {
225
+ option.classList.remove("pb_dropdown_option_selected");
226
+ });
227
+
228
+ hiddenInput.value = "";
229
+
230
+ const defaultPlaceholder = this.element.querySelector(DROPDOWN_PLACEHOLDER);
231
+ this.setTriggerElementText(defaultPlaceholder.dataset.dropdownPlaceholder);
232
+ }
233
+
234
+ setTriggerElementText(text) {
235
+ const triggerElement = this.element.querySelector(DROPDOWN_TRIGGER_DISPLAY);
236
+ if (triggerElement) {
237
+ triggerElement.textContent = text;
238
+ }
239
+ }
182
240
  }
@@ -1,3 +1,7 @@
1
- <%= pb_content_tag do %>
1
+ <%= content_tag(:div,
2
+ id: object.id,
3
+ data: object.data,
4
+ class: object.classname,
5
+ **combined_html_options) do %>
2
6
  <%= content.presence %>
3
7
  <% end %>