playbook_ui 18.2.0.pre.rc.1 → 18.2.0.pre.rc.3

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 (139) hide show
  1. checksums.yaml +4 -4
  2. data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.scss +26 -9
  3. data/app/pb_kits/playbook/pb_advanced_table/table_header.html.erb +8 -3
  4. data/app/pb_kits/playbook/pb_advanced_table/table_header.rb +19 -6
  5. data/app/pb_kits/playbook/pb_advanced_table/table_row.rb +1 -1
  6. data/app/pb_kits/playbook/pb_background/_background.tsx +3 -1
  7. data/app/pb_kits/playbook/pb_background/kit.schema.json +1 -0
  8. data/app/pb_kits/playbook/pb_caption/_caption.tsx +3 -1
  9. data/app/pb_kits/playbook/pb_caption/kit.schema.json +1 -0
  10. data/app/pb_kits/playbook/pb_container/_container.tsx +3 -1
  11. data/app/pb_kits/playbook/pb_container/kit.schema.json +1 -0
  12. data/app/pb_kits/playbook/pb_date_picker/_date_picker.scss +4 -0
  13. data/app/pb_kits/playbook/pb_date_picker/_date_picker.tsx +51 -49
  14. data/app/pb_kits/playbook/pb_date_picker/date_picker.html.erb +56 -56
  15. data/app/pb_kits/playbook/pb_date_picker/sass_partials/_calendar_input_icon.scss +1 -1
  16. data/app/pb_kits/playbook/pb_detail/_detail.tsx +3 -1
  17. data/app/pb_kits/playbook/pb_detail/kit.schema.json +1 -0
  18. data/app/pb_kits/playbook/pb_dropdown/_dropdown.tsx +6 -5
  19. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_quickpick_custom.md +7 -2
  20. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_quickpick_custom_rails.md +7 -2
  21. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_quickpick_enable_time.html.erb +33 -0
  22. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_quickpick_enable_time.jsx +42 -0
  23. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_quickpick_enable_time.md +24 -0
  24. data/app/pb_kits/playbook/pb_dropdown/docs/example.yml +2 -0
  25. data/app/pb_kits/playbook/pb_dropdown/docs/index.js +1 -0
  26. data/app/pb_kits/playbook/pb_dropdown/dropdown.html.erb +3 -0
  27. data/app/pb_kits/playbook/pb_dropdown/dropdown.rb +2 -0
  28. data/app/pb_kits/playbook/pb_dropdown/index.js +24 -10
  29. data/app/pb_kits/playbook/pb_dropdown/kit.schema.json +7 -0
  30. data/app/pb_kits/playbook/pb_dropdown/quickpick/index.ts +60 -18
  31. data/app/pb_kits/playbook/pb_dropdown/quickpick_helper.rb +92 -3
  32. data/app/pb_kits/playbook/pb_dropdown/utilities/index.ts +8 -1
  33. data/app/pb_kits/playbook/pb_dropdown/utilities/quickpickDateSync.ts +137 -0
  34. data/app/pb_kits/playbook/pb_filter/Filter/InteractiveFilter.tsx +1 -1
  35. data/app/pb_kits/playbook/pb_form/docs/_form_validation.html.erb +27 -4
  36. data/app/pb_kits/playbook/pb_form/docs/_form_validation.md +4 -4
  37. data/app/pb_kits/playbook/pb_form/docs/snippets/validation_checkbox.txt +6 -1
  38. data/app/pb_kits/playbook/pb_form/docs/snippets/validation_dropdown.txt +6 -1
  39. data/app/pb_kits/playbook/pb_form/docs/snippets/validation_multi_level_select.txt +1 -0
  40. data/app/pb_kits/playbook/pb_form/docs/snippets/validation_multi_select.txt +1 -0
  41. data/app/pb_kits/playbook/pb_form/docs/snippets/validation_phone_number.txt +1 -0
  42. data/app/pb_kits/playbook/pb_form/docs/snippets/validation_star_rating.txt +6 -1
  43. data/app/pb_kits/playbook/pb_form/docs/snippets/validation_textarea.txt +5 -1
  44. data/app/pb_kits/playbook/pb_form/docs/snippets/validation_time_zone_select.txt +1 -0
  45. data/app/pb_kits/playbook/pb_form/pb_form_validation.js +51 -34
  46. data/app/pb_kits/playbook/pb_highlight/_highlight.tsx +3 -1
  47. data/app/pb_kits/playbook/pb_highlight/kit.schema.json +1 -0
  48. data/app/pb_kits/playbook/pb_map/docs/_map_default.jsx +1 -1
  49. data/app/pb_kits/playbook/pb_map/docs/_map_default.md +3 -3
  50. data/app/pb_kits/playbook/pb_map/docs/_map_with_custom_button.jsx +1 -1
  51. data/app/pb_kits/playbook/pb_map/docs/_map_with_plugin.jsx +1 -1
  52. data/app/pb_kits/playbook/pb_map/docs/_playground.json +3 -3
  53. data/app/pb_kits/playbook/pb_map/docs/_playground.overrides.json +3 -3
  54. data/app/pb_kits/playbook/pb_multi_level_select/_multi_level_select.tsx +1 -0
  55. data/app/pb_kits/playbook/pb_multi_level_select/index.js +19 -4
  56. data/app/pb_kits/playbook/pb_multi_level_select/kit.schema.json +7 -0
  57. data/app/pb_kits/playbook/pb_multi_level_select/multi_level_select.html.erb +4 -1
  58. data/app/pb_kits/playbook/pb_multi_level_select/multi_level_select.rb +7 -3
  59. data/app/pb_kits/playbook/pb_phone_number_input/_phone_number_input.tsx +10 -7
  60. data/app/pb_kits/playbook/pb_phone_number_input/docs/_playground.json +1 -0
  61. data/app/pb_kits/playbook/pb_phone_number_input/index.ts +7 -2
  62. data/app/pb_kits/playbook/pb_phone_number_input/kit.schema.json +8 -0
  63. data/app/pb_kits/playbook/pb_phone_number_input/phone_number_input.rb +5 -1
  64. data/app/pb_kits/playbook/pb_phone_number_input/phone_number_input.test.js +12 -0
  65. data/app/pb_kits/playbook/pb_rich_text_editor/TipTap/MoreExtensionsDropdown.tsx +10 -3
  66. data/app/pb_kits/playbook/pb_rich_text_editor/TipTap/Toolbar.tsx +16 -1
  67. data/app/pb_kits/playbook/pb_rich_text_editor/docs/_playground.json +2 -3
  68. data/app/pb_kits/playbook/pb_rich_text_editor/docs/_playground.overrides.json +2 -3
  69. data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_attributes.jsx +1 -5
  70. data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_default.jsx +1 -5
  71. data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_default.md +2 -3
  72. data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_focus.jsx +1 -5
  73. data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_height.jsx +3 -13
  74. data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_inline.jsx +1 -5
  75. data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_label.jsx +2 -3
  76. data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_markdown_support.jsx +1 -2
  77. data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_min_height.jsx +3 -13
  78. data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_preview.jsx +1 -5
  79. data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_required_indicator.jsx +1 -5
  80. data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_simple.jsx +1 -5
  81. data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_sticky.jsx +1 -5
  82. data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_templates.jsx +1 -5
  83. data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_more_extensions.jsx +3 -8
  84. data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_more_extensions.md +1 -1
  85. data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_rails_default.md +2 -2
  86. data/app/pb_kits/playbook/pb_rich_text_editor/rich_text_editor.test.js +2 -1
  87. data/app/pb_kits/playbook/pb_rich_text_editor/rich_text_editor_advanced.test.js +7 -5
  88. data/app/pb_kits/playbook/pb_rich_text_editor/rich_text_editor_rails.js +15 -4
  89. data/app/pb_kits/playbook/pb_star_rating/index.js +8 -4
  90. data/app/pb_kits/playbook/pb_star_rating/kit.schema.json +7 -0
  91. data/app/pb_kits/playbook/pb_star_rating/star_rating.rb +6 -1
  92. data/app/pb_kits/playbook/pb_table/_table.tsx +70 -197
  93. data/app/pb_kits/playbook/pb_table/index.ts +53 -122
  94. data/app/pb_kits/playbook/pb_table/styles/_sticky_columns.scss +26 -3
  95. data/app/pb_kits/playbook/pb_table/styles/_vertical_border.scss +27 -8
  96. data/app/pb_kits/playbook/pb_table/utilities/stickyColumns.test.ts +266 -0
  97. data/app/pb_kits/playbook/pb_table/utilities/stickyColumns.ts +145 -0
  98. data/app/pb_kits/playbook/utilities/test/globalProps/onClick.test.js +10 -0
  99. data/dist/ai/all-schemas.json +118 -50
  100. data/dist/ai/forms.json +26 -20
  101. data/dist/ai/index.json +2 -2
  102. data/dist/ai/kits/background.schema.json +1 -0
  103. data/dist/ai/kits/button.schema.json +1 -1
  104. data/dist/ai/kits/caption.schema.json +1 -0
  105. data/dist/ai/kits/checkbox.schema.json +7 -5
  106. data/dist/ai/kits/container.schema.json +1 -0
  107. data/dist/ai/kits/date_picker.schema.json +4 -3
  108. data/dist/ai/kits/detail.schema.json +1 -0
  109. data/dist/ai/kits/dropdown.schema.json +13 -5
  110. data/dist/ai/kits/highlight.schema.json +1 -0
  111. data/dist/ai/kits/multi_level_select.schema.json +15 -6
  112. data/dist/ai/kits/phone_number_input.schema.json +18 -7
  113. data/dist/ai/kits/select.schema.json +25 -6
  114. data/dist/ai/kits/star_rating.schema.json +14 -5
  115. data/dist/ai/kits/text_input.schema.json +4 -3
  116. data/dist/ai/kits/textarea.schema.json +4 -3
  117. data/dist/ai/kits/time_picker.schema.json +4 -3
  118. data/dist/ai/kits/typeahead.schema.json +4 -3
  119. data/dist/ai/playgrounds/map.json +1 -1
  120. data/dist/ai/playgrounds/rich_text_editor.json +1 -1
  121. data/dist/chunks/{_detail-BqqzPTNr.js → _detail-Cy54syJC.js} +2 -2
  122. data/dist/chunks/{_pb_line_graph-BGyCJjgG.js → _pb_line_graph-Du7xE9vl.js} +1 -1
  123. data/dist/chunks/_table-BCqp1PAO.js +1 -0
  124. data/dist/chunks/_typeahead-CXZH3KvV.js +1 -0
  125. data/dist/chunks/{globalProps-K1DCn3il.js → globalProps-B120NbSJ.js} +1 -1
  126. data/dist/chunks/{lib-7vm9BMqp.js → lib-Buo6zHEw.js} +1 -1
  127. data/dist/chunks/quickpickDateSync-DLDx4zce.js +1 -0
  128. data/dist/chunks/{time_picker_helper-BZutIzB3.js → time_picker_helper-CYGg0UQ0.js} +1 -1
  129. data/dist/chunks/vendor.js +2 -2
  130. data/dist/playbook-rails-react-bindings.js +1 -1
  131. data/dist/playbook-rails.js +1 -1
  132. data/dist/playbook.css +1 -1
  133. data/lib/playbook/forms/builder/checkbox_field.rb +1 -0
  134. data/lib/playbook/forms/builder/collection_select_field.rb +5 -1
  135. data/lib/playbook/forms/builder/select_field.rb +5 -1
  136. data/lib/playbook/version.rb +1 -1
  137. metadata +16 -9
  138. data/dist/chunks/_table-CEZU0qUK.js +0 -1
  139. data/dist/chunks/_typeahead-C7iPR5ZF.js +0 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5db309b02e5dd780da0f53f519c006634be2dd50e13553ce229ddd8be84a5527
4
- data.tar.gz: dd7da084d43bf1060792d5dcc88dcc5fe2eaabe30d143f262083c80bef7f0a90
3
+ metadata.gz: 1c86866d416fa61cd6ef95462feacdaab4821a38f7512d171709d74ae355ca79
4
+ data.tar.gz: 881dc11beb08455d597c2fef659070af84626c562597566f69fcdb773a61f5e7
5
5
  SHA512:
6
- metadata.gz: fcc52f997e3940eae2b3c00d36620ab00d2f44fddbce652671a6a3f6223877ce3cce1310d994e405dffad6fa92629727c8b1651a777cf379dd198a810ba1c93d
7
- data.tar.gz: 18cd7637fe9d879a22a4df5505afda151de2e0a8f6bb02dc742016efe4bf4692bc2d08b50c88f078be99b0ea95c95e543dea5061489c4ffe9eada2799900a509
6
+ metadata.gz: 2a6e88281370f5ce11a7467aab89ed9db923a593f34748c39f43143488daa0f92b9f55b8eb9c1636c2f2c64215a3b092cdd5fbc3702315cc9612ef9cfe2327b0
7
+ data.tar.gz: 398a941db88d54157eb9ca15fb952d290961fc05074a7c62ec0e6246cf315ae9d75da943f31d57b6c654d99652f32036b33c4dc1fda9bd3b2454e1cf524dae50
@@ -491,12 +491,10 @@
491
491
  }
492
492
  }
493
493
 
494
- // First column separator/border
494
+ // First data column separator/border (Year when no separate checkbox column)
495
495
  .table-header-cells:first-child,
496
- .table-header-cells-custom:first-child,
497
- td:first-child,
498
- .pb_table_td:first-child,
499
- .checkbox-cell.checkbox-cell-header:first-child {
496
+ td:first-child:not(.checkbox-cell),
497
+ .pb_table_td:first-child:not(.checkbox-cell) {
500
498
  box-shadow: 1px 0px 0px 0px var(--column-border-color) !important;
501
499
  }
502
500
 
@@ -504,6 +502,14 @@
504
502
  box-shadow: inset 1px 0px 0px 0px var(--column-border-color) !important;
505
503
  }
506
504
 
505
+ // Separate checkbox column (Rails + React): separator on the first data column
506
+ .table-header-cells-custom + th[colspan="1"],
507
+ .table-header-cells-custom + .table-header-cells[colspan="1"],
508
+ td.checkbox-cell + td,
509
+ td.checkbox-cell + .pb_table_td {
510
+ box-shadow: 1px 0px 0px 0px var(--column-border-color) !important;
511
+ }
512
+
507
513
  // Color for collapsible trail
508
514
  .collapsible-trail {
509
515
  background-color: $border_light !important;
@@ -715,6 +721,12 @@
715
721
  box-shadow: 0 0 0 0 !important;
716
722
  }
717
723
 
724
+ // Re-apply after the nth-child(2) clear above (checkbox column layouts)
725
+ td.checkbox-cell + td,
726
+ td.checkbox-cell + .pb_table_td {
727
+ box-shadow: 1px 0px 0px 0px var(--column-border-color) !important;
728
+ }
729
+
718
730
  .pb_advanced_table_header,
719
731
  .pb_advanced_table_body {
720
732
  th.sticky-left,
@@ -816,10 +828,15 @@
816
828
  }
817
829
 
818
830
  .table-header-cells:first-child,
819
- .table-header-cells-custom:first-child,
820
- td:first-child,
821
- .pb_table_td:first-child,
822
- .checkbox-cell.checkbox-cell-header:first-child {
831
+ td:first-child:not(.checkbox-cell),
832
+ .pb_table_td:first-child:not(.checkbox-cell) {
833
+ box-shadow: 1px 0px 0px 0px var(--column-border-color) !important;
834
+ }
835
+
836
+ .table-header-cells-custom + th[colspan="1"],
837
+ .table-header-cells-custom + .table-header-cells[colspan="1"],
838
+ td.checkbox-cell + td,
839
+ td.checkbox-cell + .pb_table_td {
823
840
  box-shadow: 1px 0px 0px 0px var(--column-border-color) !important;
824
841
  }
825
842
 
@@ -1,14 +1,19 @@
1
1
  <%= pb_content_tag(:thead) do %>
2
2
  <% object.header_rows.each_with_index do |header_row, row_index| %>
3
+ <% is_lowest_header_row = row_index == header_rows.size - 1 %>
3
4
  <%= pb_rails("table/table_row") do %>
4
- <% if row_index == 0 && object.selectable_rows && object.enable_toggle_expansion == "none" %>
5
- <%= object.render_select_all_header %>
5
+ <% if object.selectable_rows && object.enable_toggle_expansion == "none" %>
6
+ <% if is_lowest_header_row %>
7
+ <%= object.render_select_all_header %>
8
+ <% else %>
9
+ <%= object.render_select_all_header_spacer %>
10
+ <% end %>
6
11
  <% end %>
7
12
  <% header_row.each_with_index do |cell, cell_index| %>
8
13
  <% header_component = object.header_component_info(cell, cell_index, row_index) %>
9
14
  <%= pb_rails(header_component[:name], props: header_component[:props]) do %>
10
15
  <%= pb_rails("flex", props: { align: "center", justify: object.header_flex_justify(cell, cell_index, row_index), text_align: object.header_flex_text_align(cell) }) do %>
11
- <% if cell_index.zero? && row_index === header_rows.size - 1 %>
16
+ <% if cell_index.zero? && is_lowest_header_row %>
12
17
  <% if object.selectable_rows && object.enable_toggle_expansion != "none" %>
13
18
  <%= pb_rails("flex/flex_item", props: { padding_right: "xs" }) do %>
14
19
  <%= object.render_select_all_checkbox %>
@@ -58,13 +58,8 @@ module Playbook
58
58
  # Selectable Rows No Subrows - checkboxes in their own first cell
59
59
  def render_select_all_header
60
60
  if selectable_rows
61
- additional_classes = []
62
- additional_classes << "table-header-cells-custom"
63
- additional_classes << "header-cells-with-actions" if show_actions_bar
64
- additional_classes << "checkbox-cell-header"
65
- additional_classes << "pinned-left" if responsive == "scroll"
66
61
  pb_rails("table/table_header", props: {
67
- classname: additional_classes.join(" "),
62
+ classname: select_all_header_classname,
68
63
  }) do
69
64
  pb_rails("checkbox", props: {
70
65
  id: "#{table_id ? "#{table_id}-" : ''}select-all-rows",
@@ -76,6 +71,15 @@ module Playbook
76
71
  end
77
72
  end
78
73
 
74
+ # Empty checkbox-column cell for upper multi-header rows so columns stay aligned
75
+ def render_select_all_header_spacer
76
+ if selectable_rows
77
+ pb_rails("table/table_header", props: {
78
+ classname: select_all_header_classname,
79
+ })
80
+ end
81
+ end
82
+
79
83
  # Selectable Rows w/ Subrows - checkboxes part of toggleable first cell
80
84
  def render_select_all_checkbox
81
85
  if selectable_rows
@@ -212,6 +216,15 @@ module Playbook
212
216
 
213
217
  private
214
218
 
219
+ def select_all_header_classname
220
+ additional_classes = []
221
+ additional_classes << "table-header-cells-custom"
222
+ additional_classes << "header-cells-with-actions" if show_actions_bar
223
+ additional_classes << "checkbox-cell-header"
224
+ additional_classes << "pinned-left" if responsive == "scroll"
225
+ additional_classes.join(" ")
226
+ end
227
+
215
228
  def header_layout_styles(cell)
216
229
  original_def = find_original_column_def_for_cell(cell)
217
230
  return {} unless original_def
@@ -189,7 +189,7 @@ module Playbook
189
189
 
190
190
  pb_rails("checkbox", props: {
191
191
  id: "#{prefix}select-row-#{row_id || row.object_id}",
192
- indeterminate_main: !last_row,
192
+ indeterminate_main: row_children.present?,
193
193
  indeterminate_main_labels: ["", ""],
194
194
  indeterminate_parent: indeterminate_parent,
195
195
  name: "#{prefix}select-row-#{row_id || row.object_id}",
@@ -2,6 +2,7 @@ import React, { useEffect, useState } from 'react'
2
2
  import classnames from 'classnames'
3
3
  import { buildAriaProps, buildCss, buildDataProps, buildHtmlProps } from '../utilities/props'
4
4
  import { GlobalProps, globalProps, globalInlineProps } from '../utilities/globalProps'
5
+ import { GlobalEventProps, globalEventProps } from '../utilities/globalEventProps'
5
6
 
6
7
  type BackgroundColors = 'gradient' |
7
8
  'dark' |'light' | 'white' | 'success' | 'warning' | 'error' | 'info' | 'neutral' | 'primary' | 'shadow' |
@@ -35,7 +36,7 @@ type BackgroundProps = {
35
36
  padding?: 'none' | 'xs' | 'sm' | 'md' | 'lg' | 'xl',
36
37
  tag?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'p' | 'span' | 'div' | 'tr' | 'th' | 'td' | 'thead' | 'col',
37
38
  transition?: 'fade' | 'blur' | 'scale',
38
- } & GlobalProps
39
+ } & GlobalProps & GlobalEventProps
39
40
 
40
41
  type ResponsiveProp<T> = T | {
41
42
  xs?: T,
@@ -166,6 +167,7 @@ const Background = (props: BackgroundProps): React.ReactElement => {
166
167
  {...ariaProps}
167
168
  {...dataProps}
168
169
  {...htmlProps}
170
+ {...globalEventProps(props)}
169
171
  alt={alt}
170
172
  className={classes}
171
173
  id={id}
@@ -221,6 +221,7 @@
221
221
  }
222
222
  },
223
223
  "globalProps": true,
224
+ "globalEventProps": true,
224
225
  "usage": {
225
226
  "react": {
226
227
  "import": "import { Background } from 'playbook-ui'",
@@ -2,6 +2,7 @@ import React from 'react'
2
2
  import classnames from 'classnames'
3
3
  import { buildAriaProps, buildCss, buildDataProps, buildHtmlProps } from '../utilities/props'
4
4
  import { deprecatedProps, globalProps, GlobalProps } from '../utilities/globalProps'
5
+ import { GlobalEventProps, globalEventProps } from '../utilities/globalEventProps'
5
6
 
6
7
  type CaptionProps = {
7
8
  aria?: {[key: string]: string},
@@ -15,7 +16,7 @@ type CaptionProps = {
15
16
  tag?: "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "p" | "span" | "div" | "caption",
16
17
  text?: string,
17
18
  variant?: null | "link",
18
- } & GlobalProps;
19
+ } & GlobalProps & GlobalEventProps;
19
20
 
20
21
  const Caption = (props: CaptionProps): React.ReactElement => {
21
22
  if (props.variant) deprecatedProps() //variant prop is deprecated, use color instead
@@ -62,6 +63,7 @@ const Caption = (props: CaptionProps): React.ReactElement => {
62
63
  {...ariaProps}
63
64
  {...dataProps}
64
65
  {...htmlProps}
66
+ {...globalEventProps(props)}
65
67
  className={css}
66
68
  id={id}
67
69
  >
@@ -78,6 +78,7 @@
78
78
  }
79
79
  },
80
80
  "globalProps": true,
81
+ "globalEventProps": true,
81
82
  "usage": {
82
83
  "react": {
83
84
  "import": "import { Caption } from 'playbook-ui'",
@@ -2,6 +2,7 @@ import React from 'react'
2
2
  import classnames from 'classnames'
3
3
  import { buildAriaProps, buildCss, buildDataProps, buildHtmlProps } from '../utilities/props'
4
4
  import { globalProps, GlobalProps } from '../utilities/globalProps'
5
+ import { GlobalEventProps, globalEventProps } from '../utilities/globalEventProps'
5
6
 
6
7
  type ContainerProps = {
7
8
  aria?: { [key: string]: string },
@@ -11,7 +12,7 @@ type ContainerProps = {
11
12
  htmlOptions?: { [key: string]: string | number | boolean | (() => void) | ((event: any) => void) | any },
12
13
  tag?: "div" | "span" | "a" | "button" | "option" | "table" | "tbody" | "thead" | "tfoot" | "tr" | "td" | "th" | "img" | "section" | "article" | "main" | "header" | "footer" | "nav" | "aside"
13
14
  id?: string,
14
- } & GlobalProps
15
+ } & GlobalProps & GlobalEventProps
15
16
 
16
17
  const Container = (props: ContainerProps): React.ReactElement => {
17
18
  const {
@@ -36,6 +37,7 @@ const Container = (props: ContainerProps): React.ReactElement => {
36
37
  {...ariaProps}
37
38
  {...dataProps}
38
39
  {...htmlProps}
40
+ {...globalEventProps(props)}
39
41
  className={classes}
40
42
  id={id}
41
43
  >
@@ -39,6 +39,7 @@
39
39
  }
40
40
  },
41
41
  "globalProps": true,
42
+ "globalEventProps": true,
42
43
  "usage": {
43
44
  "react": {
44
45
  "import": "import { Container } from 'playbook-ui'",
@@ -16,6 +16,10 @@
16
16
  display: block;
17
17
  }
18
18
 
19
+ .date_picker_input_container {
20
+ position: relative;
21
+ }
22
+
19
23
  @import "./sass_partials/calendar_input_icon";
20
24
  }
21
25
 
@@ -297,19 +297,57 @@ const DatePicker = (props: DatePickerProps): React.ReactElement => {
297
297
  )}
298
298
  <>
299
299
  <div className="date_picker_input_wrapper">
300
- <input
301
- aria-describedby={errorId}
302
- aria-invalid={!!error}
303
- autoComplete="off"
304
- className="date_picker_input"
305
- disabled={disableInput}
306
- id={pickerId}
307
- name={name}
308
- onChange={inputOnChange}
309
- placeholder={placeholder}
310
- style={{ cursor: getCursorStyle(filteredProps.cursor) }}
311
- value={inputValue}
312
- />
300
+ <div className="date_picker_input_container">
301
+ <input
302
+ aria-describedby={errorId}
303
+ aria-invalid={!!error}
304
+ autoComplete="off"
305
+ className="date_picker_input"
306
+ disabled={disableInput}
307
+ id={pickerId}
308
+ name={name}
309
+ onChange={inputOnChange}
310
+ placeholder={placeholder}
311
+ style={{ cursor: getCursorStyle(filteredProps.cursor) }}
312
+ value={inputValue}
313
+ />
314
+
315
+ {!hideIcon && !inLine &&
316
+ <div
317
+ className={iconWrapperClass()}
318
+ id={`cal-icon-${pickerId}`}
319
+ >
320
+ <Icon
321
+ className="cal_icon"
322
+ icon="calendar-alt"
323
+ />
324
+ </div>
325
+ }
326
+
327
+ {inLine ?
328
+ <div>
329
+ <div
330
+ className={`${iconWrapperClass()} date-picker-inline-icon-plus`}
331
+ id={`${pickerId}-icon-plus`}
332
+ >
333
+ <Icon
334
+ className="date-picker-plus-icon"
335
+ icon="plus"
336
+ />
337
+ </div>
338
+ <div
339
+ className={`${iconWrapperClass()} date-picker-inline-angle-down`}
340
+ id={`${pickerId}-angle-down`}
341
+ >
342
+ <Icon
343
+ className="angle_down_icon svg-inline--fa"
344
+ customIcon={angleDown}
345
+ />
346
+ </div>
347
+ </div>
348
+ : null
349
+ }
350
+ </div>
313
351
 
314
352
  {error &&
315
353
  <Body
@@ -322,42 +360,6 @@ const DatePicker = (props: DatePickerProps): React.ReactElement => {
322
360
  />
323
361
  }
324
362
  </div>
325
-
326
- {!hideIcon && !inLine &&
327
- <div
328
- className={iconWrapperClass()}
329
- id={`cal-icon-${pickerId}`}
330
- >
331
- <Icon
332
- className="cal_icon"
333
- icon="calendar-alt"
334
- />
335
- </div>
336
- }
337
-
338
- {inLine ?
339
- <div>
340
- <div
341
- className={`${iconWrapperClass()} date-picker-inline-icon-plus`}
342
- id={`${pickerId}-icon-plus`}
343
- >
344
- <Icon
345
- className="date-picker-plus-icon"
346
- icon="plus"
347
- />
348
- </div>
349
- <div
350
- className={`${iconWrapperClass()} date-picker-inline-angle-down`}
351
- id={`${pickerId}-angle-down`}
352
- >
353
- <Icon
354
- className="angle_down_icon svg-inline--fa"
355
- customIcon={angleDown}
356
- />
357
- </div>
358
- </div>
359
- : null
360
- }
361
363
  </>
362
364
  </div>
363
365
  </div>
@@ -18,66 +18,66 @@
18
18
  <% end %>
19
19
  </label>
20
20
  <% end %>
21
- <% if content.present? %>
22
- <%= content %>
23
- <% else %>
24
- <%= pb_rails("text_input", props: {
25
- aria: object.input_aria,
26
- autocomplete: false,
27
- cursor: object.cursor,
28
- dark: object.dark,
29
- data: object.input_data,
30
- disabled: object.disable_input,
31
- error: object.error,
32
- id: object.picker_id,
33
- margin_bottom: "none",
34
- name: object.name,
35
- placeholder: object.placeholder,
36
- required: object.required,
37
- validation: object.validation_message.present? ? { message: object.validation_message } : {},
38
- }) %>
39
- <% end %>
21
+ <div class="date_picker_input_container">
22
+ <% if content.present? %>
23
+ <%= content %>
24
+ <% else %>
25
+ <%= pb_rails("text_input", props: {
26
+ aria: object.input_aria,
27
+ autocomplete: false,
28
+ cursor: object.cursor,
29
+ dark: object.dark,
30
+ data: object.input_data,
31
+ disabled: object.disable_input,
32
+ error: object.error,
33
+ id: object.picker_id,
34
+ margin_bottom: "none",
35
+ name: object.name,
36
+ placeholder: object.placeholder,
37
+ required: object.required,
38
+ validation: object.validation_message.present? ? { message: object.validation_message } : {},
39
+ }) %>
40
+ <% end %>
41
+ <% if !object.hide_icon && !object.inline %>
42
+ <div
43
+ class="<%= object.icon_wrapper_class %>"
44
+ id="cal-icon-<%= object.picker_id %>"
45
+ >
46
+ <%= pb_rails("icon", props: {
47
+ classname: "cal_icon",
48
+ icon: "calendar-alt"
49
+ }) %>
50
+ </div>
51
+ <% end %>
52
+ <!-- Inline -->
53
+ <% if object.inline %>
54
+ <!-- Plus Icon -->
55
+ <div
56
+ class="<%= object.icon_wrapper_class %> date-picker-inline-icon-plus"
57
+ id="<%= object.picker_id %>-icon-plus"
58
+ >
59
+ <%= pb_rails("icon", props: {
60
+ classname: "plus-icon",
61
+ icon: "plus"
62
+ }) %>
63
+ </div>
64
+
65
+ <!-- Angle Down Icon -->
66
+ <div
67
+ class="<%= object.icon_wrapper_class %> date-picker-inline-angle-down"
68
+ id="<%= object.picker_id %>-angle-down"
69
+ >
70
+ <%= pb_rails("icon", props: {
71
+ classname: "angle_down_icon",
72
+ custom_icon: Playbook::Engine::root.join(angle_down_path)
73
+ }) %>
74
+ </div>
75
+ <% end %>
76
+ </div>
40
77
  <% if object.selection_type == "quickpick" %>
41
78
  <input type="hidden" id="<%= "#{object.start_date_id}" %>" name="<%= "#{object.start_date_name}" %>">
42
79
  <input type="hidden" id="<%= "#{object.end_date_id}" %>" name="<%= "#{object.end_date_name}" %>">
43
80
  <% end %>
44
-
45
- <% if !object.hide_icon && !object.inline %>
46
- <div
47
- class="<%= object.icon_wrapper_class %>"
48
- id="cal-icon-<%= object.picker_id %>"
49
- >
50
- <%= pb_rails("icon", props: {
51
- classname: "cal_icon",
52
- icon: "calendar-alt"
53
- }) %>
54
- </div>
55
- <% end %>
56
-
57
- <!-- Inline -->
58
- <% if object.inline %>
59
- <!-- Plus Icon -->
60
- <div
61
- class="<%= object.icon_wrapper_class %> date-picker-inline-icon-plus"
62
- id="<%= object.picker_id %>-icon-plus"
63
- >
64
- <%= pb_rails("icon", props: {
65
- classname: "plus-icon",
66
- icon: "plus"
67
- }) %>
68
- </div>
69
-
70
- <!-- Angle Down Icon -->
71
- <div
72
- class="<%= object.icon_wrapper_class %> date-picker-inline-angle-down"
73
- id="<%= object.picker_id %>-angle-down"
74
- >
75
- <%= pb_rails("icon", props: {
76
- classname: "angle_down_icon",
77
- custom_icon: Playbook::Engine::root.join(angle_down_path)
78
- }) %>
79
- </div>
80
- <% end %>
81
81
  </div>
82
82
 
83
83
  <%= javascript_tag do %>
@@ -3,7 +3,7 @@
3
3
  .cal_icon_wrapper {
4
4
  pointer-events: none;
5
5
  position: absolute;
6
- top: $space_md + 2;
6
+ top: 0;
7
7
  right: 0;
8
8
  border-left: 1px solid $input_border_default;
9
9
  width: $space_xl + $space_xs;
@@ -2,6 +2,7 @@ import React from 'react'
2
2
  import classnames from 'classnames'
3
3
  import { buildAriaProps, buildCss, buildDataProps, buildHtmlProps } from '../utilities/props'
4
4
  import { globalProps, GlobalProps } from '../utilities/globalProps'
5
+ import { globalEventProps, GlobalEventProps } from '../utilities/globalEventProps'
5
6
 
6
7
  type DetailProps = {
7
8
  aria?: { [key: string]: string },
@@ -15,7 +16,7 @@ type DetailProps = {
15
16
  id?: string,
16
17
  tag?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'p' | 'span' | 'div',
17
18
  text?: string,
18
- } & GlobalProps
19
+ } & GlobalProps & GlobalEventProps
19
20
 
20
21
  const Detail = (props: DetailProps): React.ReactElement => {
21
22
  const {
@@ -48,6 +49,7 @@ const Detail = (props: DetailProps): React.ReactElement => {
48
49
  {...ariaProps}
49
50
  {...dataProps}
50
51
  {...htmlProps}
52
+ {...globalEventProps(props)}
51
53
  className={classes}
52
54
  id={id}
53
55
  >
@@ -65,6 +65,7 @@
65
65
  }
66
66
  },
67
67
  "globalProps": true,
68
+ "globalEventProps": true,
68
69
  "usage": {
69
70
  "react": {
70
71
  "import": "import { Detail } from 'playbook-ui'",
@@ -20,6 +20,7 @@ import {
20
20
  separateChildComponents,
21
21
  prepareSubcomponents,
22
22
  handleClickOutside,
23
+ setQuickPickDateOnPicker,
23
24
  } from "./utilities";
24
25
 
25
26
  import { DialogContext } from "../pb_dialog/_dialog_context";
@@ -87,7 +88,7 @@ const asyncOptionValue = (option: GenericObject) => option.value ?? option.id ??
87
88
 
88
89
  type CustomQuickPickDate = {
89
90
  label: string;
90
- value: string[] | { timePeriod: string; amount: number };
91
+ value: Array<Date | string> | { timePeriod: string; amount: number };
91
92
  };
92
93
 
93
94
  type CustomQuickPickDates = {
@@ -594,12 +595,12 @@ let Dropdown = (props: DropdownProps, ref: any): React.ReactElement | null => {
594
595
 
595
596
  if (controlsStartId) {
596
597
  const startPicker = (document.querySelector(`#${controlsStartId}`) as HTMLElement & { _flatpickr?: any })?._flatpickr;
597
- startPicker?.setDate(start, true);
598
+ setQuickPickDateOnPicker(startPicker, start, "start");
598
599
  }
599
600
 
600
601
  if (controlsEndId) {
601
602
  const endPicker = (document.querySelector(`#${controlsEndId}`) as HTMLElement & { _flatpickr?: any })?._flatpickr;
602
- endPicker?.setDate(end, true);
603
+ setQuickPickDateOnPicker(endPicker, end, "end");
603
604
  }
604
605
  }
605
606
  }
@@ -711,12 +712,12 @@ let Dropdown = (props: DropdownProps, ref: any): React.ReactElement | null => {
711
712
  setTimeout(() => {
712
713
  if (controlsStartId) {
713
714
  const startPicker = (document.querySelector(`#${controlsStartId}`) as HTMLElement & { _flatpickr?: any })?._flatpickr;
714
- startPicker?.setDate(start, true);
715
+ setQuickPickDateOnPicker(startPicker, start, "start");
715
716
  }
716
717
 
717
718
  if (controlsEndId) {
718
719
  const endPicker = (document.querySelector(`#${controlsEndId}`) as HTMLElement & { _flatpickr?: any })?._flatpickr;
719
- endPicker?.setDate(end, true);
720
+ setQuickPickDateOnPicker(endPicker, end, "end");
720
721
  }
721
722
  }, 0);
722
723
  }
@@ -1,10 +1,15 @@
1
1
  The `customQuickPickDates` prop allows for defining custom quick pick date options for the dropdown. The prop accepts an object with two properties: `dates` and `override`.
2
2
 
3
3
  **The `dates` property** accepts an array of objects. Each object has `label` and `value` properties. The `label` is what will be displayed in the dropdown menu. The `value` property defines the date range that will be selected, and can be:
4
- - An array of two date strings representing a specific range (e.g., `["06/01/2022", "06/07/2022"]`)
4
+ - An array of two date strings (or `Date` objects) representing a specific range (e.g., `["06/01/2022", "06/07/2022"]`).
5
+ - **Date-only** strings get start-of-day / end-of-day when synced to `enableTime` DatePickers.
6
+ - **Timed** strings use the same formats as Rails QuickPick customs:
7
+ - US `m/d/Y` + time (optional `:SS`, optional `AM`/`PM`) — wall-clock; emit offset-less `YYYY-MM-DDTHH:MM:SS`
8
+ - Offset-less `YYYY-MM-DDTHH:MM:SS` — wall-clock; emit offset-less
9
+ - ISO-8601 with `Z` or numeric offset — absolute instant; emit keeps offset/`Z` so `new Date(iso)` preserves the instant
10
+ - `Date` objects keep their authored time (including intentional midnight / `23:59:00`).
5
11
  - An object with `timePeriod` and `amount` properties for dynamic date calculations:
6
12
  - The `timePeriod` property accepts `"days"`, `"weeks"`, `"months"`, `"quarters"`, or `"years"`, representing past time periods calculated from today.
7
13
  - The `amount` property accepts any number.
8
14
 
9
15
  **The `override` property** is a boolean that controls whether custom dates replace or append to the default quick pick options. Default is `true` (replaces defaults). Set to `false` to append your custom dates to the default quick pick options.
10
-
@@ -1,10 +1,15 @@
1
1
  The `custom_quick_pick_dates` prop allows for defining custom quick pick date options for the dropdown. The prop accepts an object with two properties: `dates` and `override`.
2
2
 
3
3
  **The `dates` property** accepts an array of objects. Each object has `label` and `value` properties. The `label` is what will be displayed in the dropdown menu. The `value` property defines the date range that will be selected, and can be:
4
- - An array of two date strings representing a specific range (e.g., `["06/01/2022", "06/07/2022"]`)
4
+ - An array of two date strings representing a specific range (e.g., `["06/01/2022", "06/07/2022"]`).
5
+ - **Date-only** strings stay date-only on the option payload (SOD/EOD applied at sync when `enable_time`).
6
+ - **Timed** strings use the same formats as React QuickPick customs:
7
+ - US `m/d/Y` + time (optional `:SS`, optional `AM`/`PM`) — wall-clock (e.g. `"06/01/2022 9:30 AM"`); emit offset-less `YYYY-MM-DDTHH:MM:SS`
8
+ - Offset-less `YYYY-MM-DDTHH:MM:SS` — wall-clock (e.g. `"2026-03-08T02:30:00"`); emit offset-less
9
+ - ISO-8601 with `Z` or numeric offset — absolute instant; emit keeps offset/`Z` (e.g. `…+00:00` / `…-05:00`) so JS `new Date(iso)` preserves the same instant
10
+ - Wall-clock and absolute emit differ on purpose: offset-less keeps the authored clock face; offset-bearing strings keep the absolute instant across Rails ↔ React. Unsupported timed free text raises.
5
11
  - An object with `time_period` and `amount` properties for dynamic date calculations:
6
12
  - The `time_period` property accepts `"days"`, `"weeks"`, `"months"`, `"quarters"`, or `"years"`, representing past time periods calculated from today.
7
13
  - The `amount` property accepts any number.
8
14
 
9
15
  **The `override` property** is a boolean that controls whether custom dates replace or append to the default quick pick options. Default is `true` (replaces defaults). Set to `false` to append your custom dates to the default quick pick options.
10
-