playbook_ui 16.9.0 → 16.10.0.pre.alpha.PLAY3053advancedtablebottompinnedrowsreact17469

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 (375) hide show
  1. checksums.yaml +4 -4
  2. data/app/pb_kits/playbook/_playbook.scss +2 -0
  3. data/app/pb_kits/playbook/pb_advanced_table/Components/RegularTableView.tsx +32 -11
  4. data/app/pb_kits/playbook/pb_advanced_table/Components/TableActionBar.tsx +5 -2
  5. data/app/pb_kits/playbook/pb_advanced_table/Context/AdvancedTableContext.tsx +27 -2
  6. data/app/pb_kits/playbook/pb_advanced_table/Hooks/useTableState.ts +19 -14
  7. data/app/pb_kits/playbook/pb_advanced_table/Utilities/CellRendererUtils.tsx +4 -2
  8. data/app/pb_kits/playbook/pb_advanced_table/Utilities/RowUtils.ts +17 -0
  9. data/app/pb_kits/playbook/pb_advanced_table/Utilities/StickyLayoutHelper.ts +100 -0
  10. data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.scss +38 -71
  11. data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.tsx +27 -77
  12. data/app/pb_kits/playbook/pb_advanced_table/advanced_table.rb +7 -0
  13. data/app/pb_kits/playbook/pb_advanced_table/advanced_table.test.jsx +128 -12
  14. data/app/pb_kits/playbook/pb_advanced_table/advanced_table_action_bar.js +31 -9
  15. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_pinned_rows.jsx +19 -2
  16. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_pinned_rows_react.md +2 -2
  17. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_row_styling.html.erb +4 -0
  18. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_row_styling.jsx +6 -2
  19. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_row_styling_rails.md +1 -0
  20. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_row_styling_react.md +1 -0
  21. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_table_props_sticky_header.html.erb +36 -44
  22. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_table_props_sticky_header.jsx +10 -19
  23. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_table_props_sticky_header_rails.md +0 -4
  24. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_table_props_sticky_header_react.md +3 -5
  25. data/app/pb_kits/playbook/pb_advanced_table/docs/_playground.json +2 -8
  26. data/app/pb_kits/playbook/pb_advanced_table/docs/_playground.overrides.json +1 -8
  27. data/app/pb_kits/playbook/pb_advanced_table/docs/example.yml +0 -1
  28. data/app/pb_kits/playbook/pb_advanced_table/docs/index.js +0 -1
  29. data/app/pb_kits/playbook/pb_advanced_table/index.js +20 -29
  30. data/app/pb_kits/playbook/pb_advanced_table/kit.schema.json +0 -12
  31. data/app/pb_kits/playbook/pb_advanced_table/table_body.rb +1 -1
  32. data/app/pb_kits/playbook/pb_advanced_table/table_row.html.erb +2 -1
  33. data/app/pb_kits/playbook/pb_advanced_table/table_row.rb +16 -2
  34. data/app/pb_kits/playbook/pb_badge/kit.schema.json +1 -1
  35. data/app/pb_kits/playbook/pb_button_toolbar/kit.schema.json +1 -1
  36. data/app/pb_kits/playbook/pb_card/card.rb +1 -1
  37. data/app/pb_kits/playbook/pb_card/kit.schema.json +2 -0
  38. data/app/pb_kits/playbook/pb_checkbox/kit.schema.json +2 -2
  39. data/app/pb_kits/playbook/pb_circle_icon_button/kit.schema.json +2 -2
  40. data/app/pb_kits/playbook/pb_date_picker/_date_picker.scss +6 -0
  41. data/app/pb_kits/playbook/pb_date_picker/_date_picker.tsx +19 -2
  42. data/app/pb_kits/playbook/pb_date_picker/date_picker.html.erb +58 -1
  43. data/app/pb_kits/playbook/pb_date_picker/date_picker.rb +3 -0
  44. data/app/pb_kits/playbook/pb_date_picker/date_picker_helper.ts +319 -65
  45. data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_year_asc.html.erb +1 -0
  46. data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_year_asc.jsx +15 -0
  47. data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_year_asc.md +1 -0
  48. data/app/pb_kits/playbook/pb_date_picker/docs/_playground.json +1 -0
  49. data/app/pb_kits/playbook/pb_date_picker/docs/example.yml +2 -0
  50. data/app/pb_kits/playbook/pb_date_picker/docs/index.js +1 -0
  51. data/app/pb_kits/playbook/pb_date_picker/kit.schema.json +9 -1
  52. data/app/pb_kits/playbook/pb_date_time/kit.schema.json +1 -1
  53. data/app/pb_kits/playbook/pb_date_time_stacked/kit.schema.json +1 -1
  54. data/app/pb_kits/playbook/pb_dialog/_dialog.scss +54 -1
  55. data/app/pb_kits/playbook/pb_dialog/_dialog.tsx +21 -5
  56. data/app/pb_kits/playbook/pb_dialog/_dialog_context.tsx +8 -2
  57. data/app/pb_kits/playbook/pb_dialog/child_kits/_dialog_header.tsx +1 -1
  58. data/app/pb_kits/playbook/pb_dialog/dialog.html.erb +5 -1
  59. data/app/pb_kits/playbook/pb_dialog/dialog.test.jsx +125 -0
  60. data/app/pb_kits/playbook/pb_dialog/index.js +11 -1
  61. data/app/pb_kits/playbook/pb_draggable/context/index.tsx +1 -1
  62. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_event_listeners_rails.md +1 -1
  63. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_independent_containers.html.erb +35 -0
  64. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_independent_containers_rails.md +8 -0
  65. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_multiple_containers_rails.md +3 -1
  66. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_multiple_containers_react.md +1 -1
  67. data/app/pb_kits/playbook/pb_draggable/docs/_playground.json +260 -19
  68. data/app/pb_kits/playbook/pb_draggable/docs/_playground.overrides.json +258 -13
  69. data/app/pb_kits/playbook/pb_draggable/docs/example.yml +1 -0
  70. data/app/pb_kits/playbook/pb_draggable/index.js +10 -3
  71. data/app/pb_kits/playbook/pb_dropdown/_dropdown.scss +122 -0
  72. data/app/pb_kits/playbook/pb_dropdown/_dropdown.tsx +114 -35
  73. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_custom_display_disabled_option.html.erb +93 -0
  74. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_custom_display_disabled_option.jsx +127 -0
  75. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_custom_display_disabled_option.md +1 -0
  76. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_disabled.html.erb +10 -0
  77. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_disabled.jsx +37 -0
  78. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_disabled_option.html.erb +10 -0
  79. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_disabled_option.jsx +37 -0
  80. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_disabled_option.md +1 -0
  81. data/app/pb_kits/playbook/pb_dropdown/docs/_playground.json +150 -237
  82. data/app/pb_kits/playbook/pb_dropdown/docs/_playground.overrides.json +58 -74
  83. data/app/pb_kits/playbook/pb_dropdown/docs/example.yml +6 -0
  84. data/app/pb_kits/playbook/pb_dropdown/docs/index.js +3 -0
  85. data/app/pb_kits/playbook/pb_dropdown/dropdown.html.erb +5 -4
  86. data/app/pb_kits/playbook/pb_dropdown/dropdown.rb +6 -1
  87. data/app/pb_kits/playbook/pb_dropdown/dropdown.test.jsx +96 -0
  88. data/app/pb_kits/playbook/pb_dropdown/dropdown_container.html.erb +1 -0
  89. data/app/pb_kits/playbook/pb_dropdown/dropdown_container.rb +2 -0
  90. data/app/pb_kits/playbook/pb_dropdown/dropdown_option.html.erb +2 -2
  91. data/app/pb_kits/playbook/pb_dropdown/dropdown_option.rb +27 -2
  92. data/app/pb_kits/playbook/pb_dropdown/dropdown_trigger.html.erb +4 -2
  93. data/app/pb_kits/playbook/pb_dropdown/dropdown_trigger.rb +2 -0
  94. data/app/pb_kits/playbook/pb_dropdown/hooks/useHandleOnKeydown.tsx +25 -5
  95. data/app/pb_kits/playbook/pb_dropdown/index.js +270 -25
  96. data/app/pb_kits/playbook/pb_dropdown/keyboard_accessibility.js +19 -10
  97. data/app/pb_kits/playbook/pb_dropdown/kit.schema.json +8 -0
  98. data/app/pb_kits/playbook/pb_dropdown/subcomponents/DropdownContainer.tsx +39 -2
  99. data/app/pb_kits/playbook/pb_dropdown/subcomponents/DropdownOption.tsx +15 -4
  100. data/app/pb_kits/playbook/pb_dropdown/subcomponents/DropdownTrigger.tsx +22 -13
  101. data/app/pb_kits/playbook/pb_file_upload/docs/_file_upload_remove_replace.html.erb +66 -0
  102. data/app/pb_kits/playbook/pb_file_upload/docs/_file_upload_remove_replace.jsx +53 -0
  103. data/app/pb_kits/playbook/pb_file_upload/docs/_file_upload_remove_replace.md +5 -0
  104. data/app/pb_kits/playbook/pb_file_upload/docs/_playground.json +2 -1
  105. data/app/pb_kits/playbook/pb_file_upload/docs/example.yml +3 -1
  106. data/app/pb_kits/playbook/pb_file_upload/docs/index.js +1 -0
  107. data/app/pb_kits/playbook/pb_file_upload/kit.schema.json +3 -3
  108. data/app/pb_kits/playbook/pb_filter/Filter/CurrentFilters.tsx +55 -28
  109. data/app/pb_kits/playbook/pb_filter/Filter/FilterDouble.tsx +4 -1
  110. data/app/pb_kits/playbook/pb_filter/Filter/FilterSingle.tsx +4 -1
  111. data/app/pb_kits/playbook/pb_filter/Filter/InteractiveFilter.tsx +277 -0
  112. data/app/pb_kits/playbook/pb_filter/_filter.scss +88 -1
  113. data/app/pb_kits/playbook/pb_filter/_filter.tsx +27 -0
  114. data/app/pb_kits/playbook/pb_filter/docs/_filter_interactive.html.erb +116 -0
  115. data/app/pb_kits/playbook/pb_filter/docs/_filter_interactive.md +12 -0
  116. data/app/pb_kits/playbook/pb_filter/docs/_filter_interactive_react.jsx +153 -0
  117. data/app/pb_kits/playbook/pb_filter/docs/_filter_interactive_react.md +10 -0
  118. data/app/pb_kits/playbook/pb_filter/docs/_filter_no_background.html.erb +1 -1
  119. data/app/pb_kits/playbook/pb_filter/docs/_playground.json +308 -5
  120. data/app/pb_kits/playbook/pb_filter/docs/_playground.overrides.json +312 -0
  121. data/app/pb_kits/playbook/pb_filter/docs/example.yml +2 -0
  122. data/app/pb_kits/playbook/pb_filter/docs/index.js +2 -1
  123. data/app/pb_kits/playbook/pb_filter/filter.html.erb +80 -3
  124. data/app/pb_kits/playbook/pb_filter/filter.rb +71 -0
  125. data/app/pb_kits/playbook/pb_filter/filter.test.js +78 -0
  126. data/app/pb_kits/playbook/pb_filter/index.ts +349 -0
  127. data/app/pb_kits/playbook/pb_filter/kit.schema.json +94 -29
  128. data/app/pb_kits/playbook/pb_fixed_confirmation_toast/docs/_playground.json +210 -14
  129. data/app/pb_kits/playbook/pb_fixed_confirmation_toast/docs/_playground.overrides.json +231 -0
  130. data/app/pb_kits/playbook/pb_fixed_confirmation_toast/kit.schema.json +1 -1
  131. data/app/pb_kits/playbook/pb_flex/docs/_playground.json +297 -38
  132. data/app/pb_kits/playbook/pb_flex/docs/_playground.overrides.json +300 -40
  133. data/app/pb_kits/playbook/pb_form/docs/_form_with_required_indicator.html.erb +20 -19
  134. data/app/pb_kits/playbook/pb_form/docs/_playground.json +1 -13
  135. data/app/pb_kits/playbook/pb_form_group/docs/_playground.json +82 -5
  136. data/app/pb_kits/playbook/pb_form_group/docs/_playground.overrides.json +91 -0
  137. data/app/pb_kits/playbook/pb_form_pill/docs/_playground.json +155 -14
  138. data/app/pb_kits/playbook/pb_form_pill/docs/_playground.overrides.json +147 -0
  139. data/app/pb_kits/playbook/pb_form_pill/kit.schema.json +1 -1
  140. data/app/pb_kits/playbook/pb_full_screen/_full_screen.scss +77 -0
  141. data/app/pb_kits/playbook/pb_full_screen/_full_screen.tsx +183 -0
  142. data/app/pb_kits/playbook/pb_full_screen/docs/_description.md +1 -0
  143. data/app/pb_kits/playbook/pb_full_screen/docs/_full_screen_content_padding.jsx +68 -0
  144. data/app/pb_kits/playbook/pb_full_screen/docs/_full_screen_content_padding.md +1 -0
  145. data/app/pb_kits/playbook/pb_full_screen/docs/_full_screen_custom_trigger.jsx +71 -0
  146. data/app/pb_kits/playbook/pb_full_screen/docs/_full_screen_custom_trigger.md +1 -0
  147. data/app/pb_kits/playbook/pb_full_screen/docs/_full_screen_default.html.erb +3 -0
  148. data/app/pb_kits/playbook/pb_full_screen/docs/_full_screen_default.jsx +63 -0
  149. data/app/pb_kits/playbook/pb_full_screen/docs/_full_screen_default.md +1 -0
  150. data/app/pb_kits/playbook/pb_full_screen/docs/_full_screen_header_text_styling.jsx +68 -0
  151. data/app/pb_kits/playbook/pb_full_screen/docs/_full_screen_header_text_styling.md +1 -0
  152. data/app/pb_kits/playbook/pb_full_screen/docs/_full_screen_sticky_header.jsx +68 -0
  153. data/app/pb_kits/playbook/pb_full_screen/docs/_full_screen_sticky_header.md +1 -0
  154. data/app/pb_kits/playbook/pb_full_screen/docs/_full_screen_table_and_filter.jsx +149 -0
  155. data/app/pb_kits/playbook/pb_full_screen/docs/_full_screen_table_and_filter.md +1 -0
  156. data/app/pb_kits/playbook/pb_full_screen/docs/_playground.json +155 -0
  157. data/app/pb_kits/playbook/pb_full_screen/docs/_playground.overrides.json +137 -0
  158. data/app/pb_kits/playbook/pb_full_screen/docs/example.yml +14 -0
  159. data/app/pb_kits/playbook/pb_full_screen/docs/index.js +6 -0
  160. data/app/pb_kits/playbook/pb_full_screen/full_screen.html.erb +12 -0
  161. data/app/pb_kits/playbook/pb_full_screen/full_screen.rb +11 -0
  162. data/app/pb_kits/playbook/pb_full_screen/full_screen.test.jsx +237 -0
  163. data/app/pb_kits/playbook/pb_full_screen/kit.schema.json +89 -0
  164. data/app/pb_kits/playbook/pb_full_screen/useFullScreen.ts +15 -0
  165. data/app/pb_kits/playbook/pb_hashtag/docs/_playground.json +72 -11
  166. data/app/pb_kits/playbook/pb_hashtag/docs/_playground.overrides.json +75 -0
  167. data/app/pb_kits/playbook/pb_highlight/docs/_playground.json +75 -4
  168. data/app/pb_kits/playbook/pb_highlight/docs/_playground.overrides.json +75 -0
  169. data/app/pb_kits/playbook/pb_home_address_street/docs/_playground.json +138 -12
  170. data/app/pb_kits/playbook/pb_home_address_street/docs/_playground.overrides.json +162 -0
  171. data/app/pb_kits/playbook/pb_icon/_icon.tsx +22 -11
  172. data/app/pb_kits/playbook/pb_icon/docs/_icon_default.jsx +1 -1
  173. data/app/pb_kits/playbook/pb_icon/docs/_playground.json +66 -41
  174. data/app/pb_kits/playbook/pb_icon/docs/_playground.overrides.json +85 -27
  175. data/app/pb_kits/playbook/pb_icon/icon.rb +5 -2
  176. data/app/pb_kits/playbook/pb_icon/kit.schema.json +3 -5
  177. data/app/pb_kits/playbook/pb_icon_button/docs/_playground.json +111 -9
  178. data/app/pb_kits/playbook/pb_icon_button/docs/_playground.overrides.json +131 -0
  179. data/app/pb_kits/playbook/pb_icon_button/kit.schema.json +1 -1
  180. data/app/pb_kits/playbook/pb_icon_circle/docs/_playground.json +92 -7
  181. data/app/pb_kits/playbook/pb_icon_circle/docs/_playground.overrides.json +108 -0
  182. data/app/pb_kits/playbook/pb_icon_stat_value/docs/_playground.json +32 -17
  183. data/app/pb_kits/playbook/pb_icon_stat_value/docs/_playground.overrides.json +81 -8
  184. data/app/pb_kits/playbook/pb_icon_value/docs/_playground.json +28 -18
  185. data/app/pb_kits/playbook/pb_icon_value/docs/_playground.overrides.json +58 -9
  186. data/app/pb_kits/playbook/pb_image/docs/_playground.json +124 -47
  187. data/app/pb_kits/playbook/pb_image/docs/_playground.overrides.json +122 -47
  188. data/app/pb_kits/playbook/pb_label_pill/docs/_playground.json +68 -6
  189. data/app/pb_kits/playbook/pb_label_pill/docs/_playground.overrides.json +85 -0
  190. data/app/pb_kits/playbook/pb_label_value/docs/_playground.json +59 -36
  191. data/app/pb_kits/playbook/pb_label_value/docs/_playground.overrides.json +101 -30
  192. data/app/pb_kits/playbook/pb_layout/docs/_playground.json +216 -10
  193. data/app/pb_kits/playbook/pb_layout/docs/_playground.overrides.json +188 -0
  194. data/app/pb_kits/playbook/pb_legend/docs/_playground.json +60 -7
  195. data/app/pb_kits/playbook/pb_legend/docs/_playground.overrides.json +77 -0
  196. data/app/pb_kits/playbook/pb_list/docs/_playground.json +165 -17
  197. data/app/pb_kits/playbook/pb_list/docs/_playground.overrides.json +191 -0
  198. data/app/pb_kits/playbook/pb_loading_inline/_loading_inline.tsx +3 -1
  199. data/app/pb_kits/playbook/pb_loading_inline/docs/_loading_inline_color.html.erb +21 -0
  200. data/app/pb_kits/playbook/pb_loading_inline/docs/_loading_inline_color.jsx +55 -0
  201. data/app/pb_kits/playbook/pb_loading_inline/docs/_loading_inline_color.md +1 -0
  202. data/app/pb_kits/playbook/pb_loading_inline/docs/_playground.json +28 -1
  203. data/app/pb_kits/playbook/pb_loading_inline/docs/_playground.overrides.json +27 -1
  204. data/app/pb_kits/playbook/pb_loading_inline/docs/example.yml +2 -0
  205. data/app/pb_kits/playbook/pb_loading_inline/docs/index.js +1 -0
  206. data/app/pb_kits/playbook/pb_loading_inline/kit.schema.json +18 -2
  207. data/app/pb_kits/playbook/pb_loading_inline/loading_inline.html.erb +1 -1
  208. data/app/pb_kits/playbook/pb_loading_inline/loading_inline.rb +3 -0
  209. data/app/pb_kits/playbook/pb_map/docs/_playground.json +164 -7
  210. data/app/pb_kits/playbook/pb_map/docs/_playground.overrides.json +180 -0
  211. data/app/pb_kits/playbook/pb_message/docs/_playground.json +114 -8
  212. data/app/pb_kits/playbook/pb_message/docs/_playground.overrides.json +144 -0
  213. data/app/pb_kits/playbook/pb_multi_level_select/_multi_level_select.scss +7 -7
  214. data/app/pb_kits/playbook/pb_multi_level_select/_multi_level_select.tsx +127 -12
  215. data/app/pb_kits/playbook/pb_multi_level_select/docs/_playground.json +310 -61
  216. data/app/pb_kits/playbook/pb_multi_level_select/docs/_playground.overrides.json +327 -44
  217. data/app/pb_kits/playbook/pb_multiple_users/docs/_playground.json +35 -6
  218. data/app/pb_kits/playbook/pb_multiple_users/docs/_playground.overrides.json +35 -6
  219. data/app/pb_kits/playbook/pb_multiple_users_stacked/docs/_playground.json +32 -21
  220. data/app/pb_kits/playbook/pb_multiple_users_stacked/docs/_playground.overrides.json +32 -21
  221. data/app/pb_kits/playbook/pb_nav/docs/_playground.json +546 -18
  222. data/app/pb_kits/playbook/pb_nav/docs/_playground.overrides.json +561 -14
  223. data/app/pb_kits/playbook/pb_online_status/docs/_playground.json +18 -23
  224. data/app/pb_kits/playbook/pb_online_status/docs/_playground.overrides.json +18 -14
  225. data/app/pb_kits/playbook/pb_overlay/docs/_playground.json +133 -14
  226. data/app/pb_kits/playbook/pb_overlay/docs/_playground.overrides.json +154 -0
  227. data/app/pb_kits/playbook/pb_pagination/docs/_playground.json +35 -14
  228. data/app/pb_kits/playbook/pb_pagination/docs/_playground.overrides.json +35 -14
  229. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_breached.html.erb +1 -1
  230. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_common.html.erb +1 -1
  231. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_meter_settings.html.erb +5 -5
  232. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_strength_change.html.erb +1 -1
  233. data/app/pb_kits/playbook/pb_passphrase/docs/_playground.json +129 -14
  234. data/app/pb_kits/playbook/pb_passphrase/docs/_playground.overrides.json +148 -0
  235. data/app/pb_kits/playbook/pb_passphrase/index.ts +58 -0
  236. data/app/pb_kits/playbook/pb_passphrase/kit.schema.json +13 -0
  237. data/app/pb_kits/playbook/pb_passphrase/passphrase.html.erb +70 -1
  238. data/app/pb_kits/playbook/pb_passphrase/passphrase.rb +70 -0
  239. data/app/pb_kits/playbook/pb_pb_bar_graph/docs/_playground.json +378 -4
  240. data/app/pb_kits/playbook/pb_pb_bar_graph/docs/_playground.overrides.json +245 -0
  241. data/app/pb_kits/playbook/pb_pb_bar_graph/kit.schema.json +1 -1
  242. data/app/pb_kits/playbook/pb_pb_circle_chart/docs/_playground.json +215 -4
  243. data/app/pb_kits/playbook/pb_pb_circle_chart/docs/_playground.overrides.json +224 -0
  244. data/app/pb_kits/playbook/pb_pb_circle_chart/kit.schema.json +1 -1
  245. data/app/pb_kits/playbook/pb_pb_gauge_chart/docs/_playground.json +149 -4
  246. data/app/pb_kits/playbook/pb_pb_gauge_chart/docs/_playground.overrides.json +162 -0
  247. data/app/pb_kits/playbook/pb_pb_gauge_chart/kit.schema.json +1 -1
  248. data/app/pb_kits/playbook/pb_pb_line_graph/docs/_playground.json +392 -4
  249. data/app/pb_kits/playbook/pb_pb_line_graph/docs/_playground.overrides.json +212 -0
  250. data/app/pb_kits/playbook/pb_pb_line_graph/kit.schema.json +1 -1
  251. data/app/pb_kits/playbook/pb_person/docs/_playground.json +27 -11
  252. data/app/pb_kits/playbook/pb_person/docs/_playground.overrides.json +34 -9
  253. data/app/pb_kits/playbook/pb_person_contact/docs/_playground.json +72 -21
  254. data/app/pb_kits/playbook/pb_person_contact/docs/_playground.overrides.json +71 -21
  255. data/app/pb_kits/playbook/pb_phone_number_input/docs/_playground.json +179 -21
  256. data/app/pb_kits/playbook/pb_phone_number_input/docs/_playground.overrides.json +180 -0
  257. data/app/pb_kits/playbook/pb_phone_number_input/kit.schema.json +2 -2
  258. data/app/pb_kits/playbook/pb_pill/docs/_playground.json +16 -49
  259. data/app/pb_kits/playbook/pb_pill/docs/_playground.overrides.json +33 -30
  260. data/app/pb_kits/playbook/pb_popover/_popover.scss +27 -0
  261. data/app/pb_kits/playbook/pb_popover/_popover.tsx +49 -16
  262. data/app/pb_kits/playbook/pb_popover/docs/_playground.json +155 -46
  263. data/app/pb_kits/playbook/pb_popover/docs/_playground.overrides.json +162 -30
  264. data/app/pb_kits/playbook/pb_popover/docs/_popover_list.jsx +9 -11
  265. data/app/pb_kits/playbook/pb_popover/index.ts +35 -4
  266. data/app/pb_kits/playbook/pb_popover/popover.html.erb +5 -2
  267. data/app/pb_kits/playbook/pb_popover/popover.test.js +212 -5
  268. data/app/pb_kits/playbook/pb_progress_pills/docs/_playground.json +26 -13
  269. data/app/pb_kits/playbook/pb_progress_pills/docs/_playground.overrides.json +24 -6
  270. data/app/pb_kits/playbook/pb_progress_simple/docs/_playground.json +50 -17
  271. data/app/pb_kits/playbook/pb_progress_simple/docs/_playground.overrides.json +41 -7
  272. data/app/pb_kits/playbook/pb_progress_step/docs/_playground.json +197 -10
  273. data/app/pb_kits/playbook/pb_progress_step/docs/_playground.overrides.json +189 -0
  274. data/app/pb_kits/playbook/pb_radio/docs/_playground.json +80 -6
  275. data/app/pb_kits/playbook/pb_radio/docs/_playground.overrides.json +82 -3
  276. data/app/pb_kits/playbook/pb_radio/kit.schema.json +1 -1
  277. data/app/pb_kits/playbook/pb_rich_text_editor/TipTap/ToolbarDropdown.tsx +12 -24
  278. data/app/pb_kits/playbook/pb_rich_text_editor/docs/_playground.json +152 -22
  279. data/app/pb_kits/playbook/pb_rich_text_editor/docs/_playground.overrides.json +153 -0
  280. data/app/pb_kits/playbook/pb_select/_select.tsx +1 -0
  281. data/app/pb_kits/playbook/pb_select/docs/_playground.json +65 -19
  282. data/app/pb_kits/playbook/pb_select/docs/_playground.overrides.json +54 -14
  283. data/app/pb_kits/playbook/pb_select/kit.schema.json +2 -2
  284. data/app/pb_kits/playbook/pb_select/select.html.erb +1 -1
  285. data/app/pb_kits/playbook/pb_selectable_card/docs/_playground.json +75 -82
  286. data/app/pb_kits/playbook/pb_selectable_card/docs/_playground.overrides.json +76 -76
  287. data/app/pb_kits/playbook/pb_selectable_card/kit.schema.json +2 -2
  288. data/app/pb_kits/playbook/pb_selectable_card_icon/docs/_playground.json +105 -15
  289. data/app/pb_kits/playbook/pb_selectable_card_icon/docs/_playground.overrides.json +106 -0
  290. data/app/pb_kits/playbook/pb_selectable_card_icon/kit.schema.json +2 -2
  291. data/app/pb_kits/playbook/pb_selectable_icon/docs/_playground.json +37 -21
  292. data/app/pb_kits/playbook/pb_selectable_icon/docs/_playground.overrides.json +35 -18
  293. data/app/pb_kits/playbook/pb_selectable_icon/kit.schema.json +1 -1
  294. data/app/pb_kits/playbook/pb_selectable_list/docs/_playground.json +174 -12
  295. data/app/pb_kits/playbook/pb_selectable_list/docs/_playground.overrides.json +162 -10
  296. data/app/pb_kits/playbook/pb_skeleton_loading/docs/_playground.json +68 -6
  297. data/app/pb_kits/playbook/pb_skeleton_loading/docs/_playground.overrides.json +80 -0
  298. data/app/pb_kits/playbook/pb_source/docs/_playground.json +67 -6
  299. data/app/pb_kits/playbook/pb_source/docs/_playground.overrides.json +80 -0
  300. data/app/pb_kits/playbook/pb_star_rating/docs/_playground.json +28 -53
  301. data/app/pb_kits/playbook/pb_star_rating/docs/_playground.overrides.json +33 -32
  302. data/app/pb_kits/playbook/pb_star_rating/kit.schema.json +1 -1
  303. data/app/pb_kits/playbook/pb_stat_change/docs/_playground.json +15 -9
  304. data/app/pb_kits/playbook/pb_stat_change/docs/_playground.overrides.json +15 -5
  305. data/app/pb_kits/playbook/pb_stat_value/docs/_playground.json +19 -9
  306. data/app/pb_kits/playbook/pb_stat_value/docs/_playground.overrides.json +18 -7
  307. data/app/pb_kits/playbook/pb_stat_value/kit.schema.json +1 -1
  308. data/app/pb_kits/playbook/pb_table/docs/_playground.json +223 -21
  309. data/app/pb_kits/playbook/pb_table/docs/_playground.overrides.json +176 -0
  310. data/app/pb_kits/playbook/pb_text_input/docs/_playground.json +44 -5
  311. data/app/pb_kits/playbook/pb_text_input/docs/_playground.overrides.json +39 -3
  312. data/app/pb_kits/playbook/pb_text_input/kit.schema.json +3 -3
  313. data/app/pb_kits/playbook/pb_textarea/docs/_playground.json +35 -3
  314. data/app/pb_kits/playbook/pb_textarea/docs/_playground.overrides.json +28 -3
  315. data/app/pb_kits/playbook/pb_textarea/kit.schema.json +1 -1
  316. data/app/pb_kits/playbook/pb_time/docs/_playground.json +28 -14
  317. data/app/pb_kits/playbook/pb_time/docs/_playground.overrides.json +26 -13
  318. data/app/pb_kits/playbook/pb_time_picker/_time_picker.scss +42 -0
  319. data/app/pb_kits/playbook/pb_time_picker/_time_picker.tsx +309 -167
  320. data/app/pb_kits/playbook/pb_time_picker/docs/_playground.json +36 -30
  321. data/app/pb_kits/playbook/pb_time_picker/docs/_playground.overrides.json +31 -26
  322. data/app/pb_kits/playbook/pb_time_picker/index.ts +263 -11
  323. data/app/pb_kits/playbook/pb_time_range_inline/docs/_playground.json +63 -9
  324. data/app/pb_kits/playbook/pb_time_range_inline/docs/_playground.overrides.json +69 -0
  325. data/app/pb_kits/playbook/pb_time_stacked/docs/_playground.json +30 -9
  326. data/app/pb_kits/playbook/pb_time_stacked/docs/_playground.overrides.json +30 -9
  327. data/app/pb_kits/playbook/pb_timeline/docs/_playground.json +178 -6
  328. data/app/pb_kits/playbook/pb_timeline/docs/_playground.overrides.json +165 -0
  329. data/app/pb_kits/playbook/pb_timestamp/docs/_playground.json +36 -21
  330. data/app/pb_kits/playbook/pb_timestamp/docs/_playground.overrides.json +35 -20
  331. data/app/pb_kits/playbook/pb_toggle/docs/_playground.json +24 -13
  332. data/app/pb_kits/playbook/pb_toggle/docs/_playground.overrides.json +20 -12
  333. data/app/pb_kits/playbook/pb_toggle/kit.schema.json +2 -2
  334. data/app/pb_kits/playbook/pb_tooltip/docs/_playground.json +42 -23
  335. data/app/pb_kits/playbook/pb_tooltip/docs/_playground.overrides.json +35 -15
  336. data/app/pb_kits/playbook/pb_typeahead/_typeahead.tsx +109 -3
  337. data/app/pb_kits/playbook/pb_typeahead/docs/_playground.json +124 -44
  338. data/app/pb_kits/playbook/pb_typeahead/docs/_playground.overrides.json +98 -31
  339. data/app/pb_kits/playbook/pb_typeahead/kit.schema.json +8 -2
  340. data/app/pb_kits/playbook/pb_user/docs/_playground.json +33 -15
  341. data/app/pb_kits/playbook/pb_user/docs/_playground.overrides.json +32 -15
  342. data/app/pb_kits/playbook/pb_user_badge/docs/_playground.json +26 -12
  343. data/app/pb_kits/playbook/pb_user_badge/docs/_playground.overrides.json +26 -9
  344. data/app/pb_kits/playbook/pb_weekday_stacked/docs/_playground.json +32 -5
  345. data/app/pb_kits/playbook/pb_weekday_stacked/docs/_playground.overrides.json +30 -4
  346. data/app/pb_kits/playbook/tokens/_colors.scss +5 -1
  347. data/app/pb_kits/playbook/utilities/_border.scss +262 -0
  348. data/app/pb_kits/playbook/utilities/floatingPortalHosts.ts +565 -0
  349. data/app/pb_kits/playbook/utilities/global-props.schema.json +98 -0
  350. data/app/pb_kits/playbook/utilities/globalProps.ts +83 -1
  351. data/app/pb_kits/playbook/utilities/icons/allicons.tsx +38 -0
  352. data/app/pb_kits/playbook/utilities/test/globalProps/border.test.js +66 -0
  353. data/dist/chunks/{_pb_line_graph-B870s9g1.js → _pb_line_graph-C2H9vs_8.js} +1 -1
  354. data/dist/chunks/_typeahead-Du8dRYaM.js +5 -0
  355. data/dist/chunks/globalProps-DIAZ03-L.js +6 -0
  356. data/dist/chunks/lib-ZHDedNfP.js +29 -0
  357. data/dist/chunks/time_picker_helper-CVMV9ync.js +1 -0
  358. data/dist/chunks/vendor.js +5 -5
  359. data/dist/menu.yml +7 -0
  360. data/dist/playbook-rails-react-bindings.js +1 -1
  361. data/dist/playbook-rails.js +1 -1
  362. data/dist/playbook.css +1 -1
  363. data/lib/playbook/border.rb +87 -0
  364. data/lib/playbook/classnames.rb +1 -0
  365. data/lib/playbook/forms/builder/form_field_builder.rb +2 -0
  366. data/lib/playbook/kit_base.rb +2 -0
  367. data/lib/playbook/pb_forms_global_props_helper.rb +15 -0
  368. data/lib/playbook/version.rb +2 -2
  369. metadata +93 -9
  370. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_fullscreen.jsx +0 -92
  371. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_fullscreen.md +0 -3
  372. data/dist/chunks/_typeahead-jMN-A0_C.js +0 -5
  373. data/dist/chunks/globalProps-BInmh-C7.js +0 -6
  374. data/dist/chunks/lib-CVYIIiwI.js +0 -29
  375. data/dist/chunks/time_picker_helper-Bx8nzyM8.js +0 -1
@@ -1,12 +1,13 @@
1
1
  {
2
+ "hiddenProps": ["inputOptions", "onChange", "onClose", "value"],
2
3
  "groups": [
3
4
  {
4
5
  "name": "Content",
5
- "props": ["label", "name", "value", "defaultTime"]
6
+ "props": ["label", "name", "defaultTime"]
6
7
  },
7
8
  {
8
9
  "name": "Appearance",
9
- "props": ["timeFormat", "showTimezone"]
10
+ "props": ["timeFormat", "showTimezone", "dark"]
10
11
  },
11
12
  {
12
13
  "name": "Validation",
@@ -19,10 +20,6 @@
19
20
  "error",
20
21
  "validationMessage"
21
22
  ]
22
- },
23
- {
24
- "name": "Advanced",
25
- "props": ["inputOptions", "onChange", "onClose"]
26
23
  }
27
24
  ],
28
25
  "presets": [
@@ -63,7 +60,7 @@
63
60
  }
64
61
  },
65
62
  {
66
- "name": "Required field",
63
+ "name": "Required Field",
67
64
  "props": {
68
65
  "label": "Appointment",
69
66
  "name": "appointment_time",
@@ -71,26 +68,34 @@
71
68
  "requiredIndicator": true,
72
69
  "defaultTime": "10:00 AM"
73
70
  }
74
- },
75
- {
76
- "name": "Disabled",
77
- "props": {
78
- "label": "Locked",
79
- "name": "locked_time",
80
- "disabled": true,
81
- "defaultTime": "12:00 PM"
82
- }
83
- },
84
- {
85
- "name": "Error state",
86
- "props": {
87
- "label": "Invalid slot",
88
- "name": "error_time",
89
- "error": "Selected time is unavailable",
90
- "defaultTime": "11:45 AM"
91
- }
92
71
  }
93
72
  ],
94
73
  "conditionals": {},
95
- "hints": {}
74
+ "hints": {
75
+ "default": {
76
+ "presetName": "Default",
77
+ "message": "Default uses defaultTime so the picker initializes with a value while remaining internally editable.",
78
+ "type": "info"
79
+ },
80
+ "twenty_four_hour": {
81
+ "presetName": "24-hour",
82
+ "message": "24-hour switches timeFormat to the 24hour display and input pattern.",
83
+ "type": "info"
84
+ },
85
+ "with_timezone": {
86
+ "presetName": "With timezone",
87
+ "message": "With timezone shows the timezone label next to the selected time.",
88
+ "type": "info"
89
+ },
90
+ "business_hours": {
91
+ "presetName": "Business hours",
92
+ "message": "Business hours combines minTime and maxTime to constrain available selections.",
93
+ "type": "info"
94
+ },
95
+ "required_field": {
96
+ "presetName": "Required Field",
97
+ "message": "Required Field combines required and requiredIndicator for validation-ready forms.",
98
+ "type": "info"
99
+ }
100
+ }
96
101
  }
@@ -1,4 +1,16 @@
1
1
  import PbEnhancedElement from '../pb_enhanced_element'
2
+ import {
3
+ announceFloatingKitOpen,
4
+ nextPortaledFloatingZIndex,
5
+ PB_FLOATING_OWNER_ATTR,
6
+ positionDropdownPortalToWrapper,
7
+ recordPortaledMenuPointerDown,
8
+ resolveFloatingOwnerId,
9
+ resolvePortaledFloatingZIndex,
10
+ resolvePortaledKitHost,
11
+ subscribeFloatingKitOpen,
12
+ subscribeFloatingKitReposition,
13
+ } from '../utilities/floatingPortalHosts'
2
14
  import {
3
15
  parseTime,
4
16
  parseTimeToMinutes,
@@ -80,6 +92,20 @@ export default class PbTimePicker extends PbEnhancedElement {
80
92
  private formElement: HTMLFormElement | null = null
81
93
  private initialized = false
82
94
 
95
+ private portalHost: HTMLElement | null = null
96
+ private floatingOwnerId: string | null = null
97
+ private useMenuPortal = false
98
+ private portalShell: HTMLElement | null = null
99
+ private _portalParent: Node | null = null
100
+ private _portalNext: ChildNode | null = null
101
+ private _floatingResolved = false
102
+ private _unsubscribePortalReposition: (() => void) | null = null
103
+ private boundApplyPortalPosition: (() => void) | null = null
104
+ private timePickerWrapper: HTMLElement | null = null
105
+ private _popoverObserver: MutationObserver | null = null
106
+ private _unsubscribeKitOpen: (() => void) | null = null
107
+ private _activePortalZIndex: string | undefined
108
+
83
109
  private initializeState(): void {
84
110
  if (this.initialized) return
85
111
  this.initialized = true
@@ -131,6 +157,8 @@ export default class PbTimePicker extends PbEnhancedElement {
131
157
  this.amCard = element.querySelector('.pb_time_picker_meridiem_am') as HTMLElement | null
132
158
  this.pmCard = element.querySelector('.pb_time_picker_meridiem_pm') as HTMLElement | null
133
159
 
160
+ this.timePickerWrapper = element.querySelector('.time_picker_wrapper')
161
+
134
162
  this.handleInvalidBound = this.handleInvalid.bind(this)
135
163
  this.handleClickOutsideBound = this.handleClickOutside.bind(this)
136
164
  this.handleMeridiemKeyDownBound = this.handleMeridiemKeyDown.bind(this)
@@ -146,13 +174,24 @@ export default class PbTimePicker extends PbEnhancedElement {
146
174
  this.updateUI()
147
175
  this.bindEvents()
148
176
  this.bindFormValidation()
177
+ this.bindPopoverHideClose()
178
+ this._unsubscribeKitOpen = subscribeFloatingKitOpen(({ kitKind }) => {
179
+ if (kitKind !== 'time-picker' && this.showDropdown) {
180
+ this.closeDropdown(true)
181
+ }
182
+ })
149
183
  document.addEventListener('invalid', this.handleInvalidBound, true)
150
184
  }
151
185
 
152
186
  disconnect(): void {
187
+ this._unsubscribeKitOpen?.()
188
+ this._unsubscribeKitOpen = null
189
+ this._popoverObserver?.disconnect()
190
+ this._popoverObserver = null
191
+ this.unmountPortalMenu()
153
192
  this.formElement?.removeEventListener('submit', this.handleFormSubmitBound, true)
154
193
  document.removeEventListener('invalid', this.handleInvalidBound, true)
155
- document.removeEventListener('mousedown', this.handleClickOutsideBound)
194
+ document.removeEventListener('mousedown', this.handleClickOutsideBound, true)
156
195
  this.amRadio?.removeEventListener('keydown', this.handleMeridiemKeyDownBound)
157
196
  this.pmRadio?.removeEventListener('keydown', this.handleMeridiemKeyDownBound)
158
197
  this.unbindMainInputEvents()
@@ -204,7 +243,11 @@ export default class PbTimePicker extends PbEnhancedElement {
204
243
  option.dataset.hour = h.toString()
205
244
  option.textContent = this.timeFormat === '24hour' ? h.toString().padStart(2, '0') : h.toString()
206
245
  option.addEventListener('mousedown', (e) => {
207
- e.preventDefault()
246
+ e.stopPropagation()
247
+ this.recordPortaledMenuPointer(e)
248
+ })
249
+ option.addEventListener('click', (e) => {
250
+ e.stopPropagation()
208
251
  this.handleHourOptionClick(h)
209
252
  })
210
253
  this.hourDropdown.appendChild(option)
@@ -217,7 +260,11 @@ export default class PbTimePicker extends PbEnhancedElement {
217
260
  option.dataset.minute = m.toString()
218
261
  option.textContent = m.toString().padStart(2, '0')
219
262
  option.addEventListener('mousedown', (e) => {
220
- e.preventDefault()
263
+ e.stopPropagation()
264
+ this.recordPortaledMenuPointer(e)
265
+ })
266
+ option.addEventListener('click', (e) => {
267
+ e.stopPropagation()
221
268
  this.handleMinuteOptionClick(m)
222
269
  })
223
270
  this.minuteDropdown.appendChild(option)
@@ -263,10 +310,32 @@ export default class PbTimePicker extends PbEnhancedElement {
263
310
  this.hourInput.classList.toggle('invalid', invalidSelection)
264
311
  this.minuteInput.classList.toggle('invalid', invalidSelection)
265
312
 
266
- this.dropdownContainer.hidden = !this.showDropdown || this.disabled
313
+ const isPortaled = this.dropdownContainer.dataset.pbTimePickerPortaled === 'true'
314
+ if (!isPortaled) {
315
+ this.dropdownContainer.hidden = !this.showDropdown || this.disabled
316
+ } else if (!this.showDropdown || this.disabled) {
317
+ this.dropdownContainer.hidden = true
318
+ } else {
319
+ this.dropdownContainer.hidden = false
320
+ }
321
+
267
322
  this.hourDropdown.hidden = !this.showHourDropdown
268
323
  this.minuteDropdown.hidden = !this.showMinuteDropdown
269
324
 
325
+ if (isPortaled && this._activePortalZIndex) {
326
+ const portalZIndex = this._activePortalZIndex
327
+ if (this.showHourDropdown) {
328
+ this.hourDropdown.style.zIndex = portalZIndex
329
+ } else {
330
+ this.hourDropdown.style.removeProperty('z-index')
331
+ }
332
+ if (this.showMinuteDropdown) {
333
+ this.minuteDropdown.style.zIndex = portalZIndex
334
+ } else {
335
+ this.minuteDropdown.style.removeProperty('z-index')
336
+ }
337
+ }
338
+
270
339
  this.hourDropdown.querySelectorAll('.time_dropdown_option').forEach((el) => {
271
340
  const option = el as HTMLElement
272
341
  const h = parseInt(option.dataset.hour || '0', 10)
@@ -317,6 +386,13 @@ export default class PbTimePicker extends PbEnhancedElement {
317
386
  this.removeValidationErrorMessage()
318
387
  }
319
388
 
389
+ if (
390
+ this.showDropdown &&
391
+ this.useMenuPortal &&
392
+ this.dropdownContainer.dataset.pbTimePickerPortaled === 'true'
393
+ ) {
394
+ requestAnimationFrame(() => this.applyPortalPosition())
395
+ }
320
396
  }
321
397
 
322
398
  private scrollHourDropdownToSelected(): void {
@@ -469,19 +545,191 @@ export default class PbTimePicker extends PbEnhancedElement {
469
545
  this.element.querySelector(VALIDATION_ERROR_SELECTOR)?.remove()
470
546
  }
471
547
 
548
+ private recordPortaledMenuPointer(event: MouseEvent): void {
549
+ if (!this.useMenuPortal || !this.floatingOwnerId) return
550
+ recordPortaledMenuPointerDown(
551
+ this.floatingOwnerId,
552
+ event.clientX,
553
+ event.clientY,
554
+ )
555
+ }
556
+
557
+ private ensureFloatingPortalConfig(): void {
558
+ if (!this._floatingResolved) {
559
+ this.portalHost = resolvePortaledKitHost(this.element as HTMLElement, null)
560
+ this.useMenuPortal = Boolean(this.portalHost)
561
+ this._floatingResolved = true
562
+ }
563
+ this.floatingOwnerId = resolveFloatingOwnerId(this.element as HTMLElement)
564
+ }
565
+
566
+ private mountPortalMenu(): void {
567
+ if (!this.useMenuPortal || !this.portalHost) return
568
+ const container = this.dropdownContainer
569
+ if (container.dataset.pbTimePickerPortaled === 'true') return
570
+
571
+ this._portalParent = container.parentNode
572
+ this._portalNext = container.nextSibling
573
+
574
+ const shell = document.createElement('div')
575
+ const shellClasses = [
576
+ 'pb_time_picker',
577
+ 'pb_time_picker_floating_shell',
578
+ 'pb_time_picker_panel_portal',
579
+ this.element.classList.contains('error') ? 'error' : '',
580
+ this.element.classList.contains('disabled') ? 'disabled' : '',
581
+ this.element.classList.contains('dark') ? 'dark' : '',
582
+ ].filter(Boolean)
583
+ shell.className = shellClasses.join(' ')
584
+ const ownerId = this.floatingOwnerId ?? resolveFloatingOwnerId(this.element as HTMLElement)
585
+ if (ownerId) {
586
+ shell.setAttribute(PB_FLOATING_OWNER_ATTR, ownerId)
587
+ container.setAttribute(PB_FLOATING_OWNER_ATTR, ownerId)
588
+ this.hourDropdown?.setAttribute(PB_FLOATING_OWNER_ATTR, ownerId)
589
+ this.minuteDropdown?.setAttribute(PB_FLOATING_OWNER_ATTR, ownerId)
590
+ }
591
+
592
+ shell.appendChild(container)
593
+ this.portalHost.appendChild(shell)
594
+ this.portalShell = shell
595
+ container.dataset.pbTimePickerPortaled = 'true'
596
+ }
597
+
598
+ private clearPortalPanelStyles(panel: HTMLElement): void {
599
+ panel.style.removeProperty('position')
600
+ panel.style.removeProperty('left')
601
+ panel.style.removeProperty('top')
602
+ panel.style.removeProperty('width')
603
+ panel.style.removeProperty('margin')
604
+ panel.style.removeProperty('pointer-events')
605
+ panel.style.removeProperty('z-index')
606
+
607
+ const selection = panel.querySelector('.pb_time_selection') as HTMLElement | null
608
+ if (selection) {
609
+ selection.style.removeProperty('max-height')
610
+ selection.style.removeProperty('overflow')
611
+ }
612
+ }
613
+
614
+ private closeHourMinuteDropdowns(): void {
615
+ this.showHourDropdown = false
616
+ this.showMinuteDropdown = false
617
+ if (this.hourDropdown) this.hourDropdown.hidden = true
618
+ if (this.minuteDropdown) this.minuteDropdown.hidden = true
619
+ }
620
+
621
+ private unmountPortalMenu(): void {
622
+ if (this._unsubscribePortalReposition) {
623
+ this._unsubscribePortalReposition()
624
+ this._unsubscribePortalReposition = null
625
+ }
626
+ if (this.boundApplyPortalPosition) {
627
+ window.removeEventListener('resize', this.boundApplyPortalPosition)
628
+ this.boundApplyPortalPosition = null
629
+ }
630
+
631
+ const container = this.dropdownContainer
632
+ if (!container || container.dataset.pbTimePickerPortaled !== 'true') {
633
+ return
634
+ }
635
+
636
+ this.closeHourMinuteDropdowns()
637
+
638
+ delete container.dataset.pbTimePickerPortaled
639
+ container.removeAttribute(PB_FLOATING_OWNER_ATTR)
640
+ this.hourDropdown?.removeAttribute(PB_FLOATING_OWNER_ATTR)
641
+ this.minuteDropdown?.removeAttribute(PB_FLOATING_OWNER_ATTR)
642
+ this.clearPortalPanelStyles(container)
643
+
644
+ if (container.parentNode === this.portalShell && this._portalParent) {
645
+ if (this._portalNext && this._portalNext.parentNode === this._portalParent) {
646
+ this._portalParent.insertBefore(container, this._portalNext)
647
+ } else {
648
+ this._portalParent.appendChild(container)
649
+ }
650
+ }
651
+ this._portalParent = null
652
+ this._portalNext = null
653
+
654
+ if (this.portalShell) {
655
+ this.portalShell.remove()
656
+ }
657
+ this.portalShell = null
658
+ }
659
+
660
+ private bindPopoverHideClose(): void {
661
+ const tooltip = this.element.closest('.pb_popover_tooltip') as HTMLElement | null
662
+ if (!tooltip) return
663
+
664
+ this._popoverObserver = new MutationObserver(() => {
665
+ if (!tooltip.classList.contains('show') && (this.showDropdown || this.portalShell)) {
666
+ this.showDropdown = false
667
+ document.removeEventListener('mousedown', this.handleClickOutsideBound, true)
668
+ this.unmountPortalMenu()
669
+ this.updateUI()
670
+ }
671
+ })
672
+ this._popoverObserver.observe(tooltip, { attributes: true, attributeFilter: ['class'] })
673
+ }
674
+
675
+ private applyPortalPosition(): void {
676
+ if (
677
+ !this.useMenuPortal ||
678
+ !this.portalHost ||
679
+ !this.portalShell ||
680
+ !this.timePickerWrapper
681
+ ) {
682
+ return
683
+ }
684
+
685
+ positionDropdownPortalToWrapper({
686
+ panel: this.portalShell,
687
+ wrapperViewportRect: this.timePickerWrapper.getBoundingClientRect(),
688
+ positionHost: this.portalHost,
689
+ preferBelow: true,
690
+ matchWrapperWidth: false,
691
+ zIndex: this._activePortalZIndex,
692
+ })
693
+ }
694
+
472
695
  private openDropdown(): void {
696
+ this.ensureFloatingPortalConfig()
697
+ this._activePortalZIndex = this.portalHost
698
+ ? resolvePortaledFloatingZIndex(
699
+ this.portalHost,
700
+ nextPortaledFloatingZIndex(),
701
+ )
702
+ : undefined
703
+ announceFloatingKitOpen('time-picker', this.floatingOwnerId)
704
+ if (this.useMenuPortal) {
705
+ this.mountPortalMenu()
706
+ }
707
+
473
708
  this.showDropdown = true
474
- document.addEventListener('mousedown', this.handleClickOutsideBound)
709
+ document.addEventListener('mousedown', this.handleClickOutsideBound, true)
475
710
  this.updateUI()
711
+
712
+ if (this.useMenuPortal) {
713
+ this.applyPortalPosition()
714
+ this.boundApplyPortalPosition = this.applyPortalPosition.bind(this)
715
+ window.addEventListener('resize', this.boundApplyPortalPosition)
716
+ if (this._unsubscribePortalReposition) {
717
+ this._unsubscribePortalReposition()
718
+ }
719
+ this._unsubscribePortalReposition = subscribeFloatingKitReposition(
720
+ this.boundApplyPortalPosition,
721
+ )
722
+ window.requestAnimationFrame(() => this.applyPortalPosition())
723
+ }
476
724
  }
477
725
 
478
726
  private closeDropdown(skipValidation = false): void {
479
- this.showHourDropdown = false
480
- this.showMinuteDropdown = false
481
- document.removeEventListener('mousedown', this.handleClickOutsideBound)
727
+ this.closeHourMinuteDropdowns()
728
+ document.removeEventListener('mousedown', this.handleClickOutsideBound, true)
482
729
 
483
730
  if (!this.hasSelectedTime) {
484
731
  this.showDropdown = false
732
+ this.unmountPortalMenu()
485
733
  this.updateUI()
486
734
  return
487
735
  }
@@ -520,6 +768,9 @@ export default class PbTimePicker extends PbEnhancedElement {
520
768
  this.showDropdown = false
521
769
  }
522
770
 
771
+ if (!this.showDropdown) {
772
+ this.unmountPortalMenu()
773
+ }
523
774
  this.updateUI()
524
775
  }
525
776
 
@@ -546,9 +797,10 @@ export default class PbTimePicker extends PbEnhancedElement {
546
797
  }
547
798
 
548
799
  private handleClickOutside(event: MouseEvent): void {
549
- if (!this.element.contains(event.target as Node)) {
550
- this.closeDropdown()
551
- }
800
+ const target = event.target as Node
801
+ if (this.element.contains(target)) return
802
+ if (this.portalShell?.contains(target)) return
803
+ this.closeDropdown()
552
804
  }
553
805
 
554
806
  private handleInputKeyDown = (e: KeyboardEvent): void => {
@@ -9,24 +9,78 @@
9
9
  },
10
10
  "groups": [
11
11
  {
12
- "name": "Props",
12
+ "name": "Content",
13
13
  "props": [
14
- "alignment",
15
- "size",
16
- "dark",
17
- "icon",
18
- "timezone",
19
14
  "startTime",
20
- "endTime"
15
+ "endTime",
16
+ "timezone"
17
+ ]
18
+ },
19
+ {
20
+ "name": "Appearance",
21
+ "props": [
22
+ "icon",
23
+ "size",
24
+ "alignment",
25
+ "dark"
21
26
  ]
22
27
  }
23
28
  ],
24
29
  "presets": [
25
30
  {
26
31
  "name": "Default",
27
- "props": {}
32
+ "props": {
33
+ "startTime": "2026-04-09T15:30:00.000Z",
34
+ "endTime": "2026-04-09T17:00:00.000Z"
35
+ }
36
+ },
37
+ {
38
+ "name": "Compact",
39
+ "props": {
40
+ "startTime": "2026-04-09T15:30:00.000Z",
41
+ "endTime": "2026-04-09T17:00:00.000Z",
42
+ "size": "xs"
43
+ }
44
+ },
45
+ {
46
+ "name": "With Icon",
47
+ "props": {
48
+ "startTime": "2026-04-09T09:00:00.000Z",
49
+ "endTime": "2026-04-09T10:30:00.000Z",
50
+ "icon": true
51
+ }
52
+ },
53
+ {
54
+ "name": "Vertical Timezone",
55
+ "props": {
56
+ "startTime": "2026-04-09T20:00:00.000Z",
57
+ "endTime": "2026-04-09T21:30:00.000Z",
58
+ "alignment": "vertical",
59
+ "timezone": true
60
+ }
28
61
  }
29
62
  ],
30
63
  "conditionals": {},
31
- "hints": {}
64
+ "hints": {
65
+ "default": {
66
+ "presetName": "Default",
67
+ "message": "Default renders a start and end Date as an inline time range.",
68
+ "type": "info"
69
+ },
70
+ "compact": {
71
+ "presetName": "Compact",
72
+ "message": "Compact switches size to xs for denser layouts.",
73
+ "type": "info"
74
+ },
75
+ "with_icon": {
76
+ "presetName": "With Icon",
77
+ "message": "With Icon adds the clock icon before the range.",
78
+ "type": "info"
79
+ },
80
+ "vertical_timezone": {
81
+ "presetName": "Vertical Timezone",
82
+ "message": "Vertical Timezone stacks the range and includes the timezone label.",
83
+ "type": "info"
84
+ }
85
+ }
32
86
  }
@@ -0,0 +1,69 @@
1
+ {
2
+ "groups": [
3
+ {
4
+ "name": "Content",
5
+ "props": ["startTime", "endTime", "timezone"]
6
+ },
7
+ {
8
+ "name": "Appearance",
9
+ "props": ["icon", "size", "alignment", "dark"]
10
+ }
11
+ ],
12
+ "presets": [
13
+ {
14
+ "name": "Default",
15
+ "props": {
16
+ "startTime": "2026-04-09T15:30:00.000Z",
17
+ "endTime": "2026-04-09T17:00:00.000Z"
18
+ }
19
+ },
20
+ {
21
+ "name": "Compact",
22
+ "props": {
23
+ "startTime": "2026-04-09T15:30:00.000Z",
24
+ "endTime": "2026-04-09T17:00:00.000Z",
25
+ "size": "xs"
26
+ }
27
+ },
28
+ {
29
+ "name": "With Icon",
30
+ "props": {
31
+ "startTime": "2026-04-09T09:00:00.000Z",
32
+ "endTime": "2026-04-09T10:30:00.000Z",
33
+ "icon": true
34
+ }
35
+ },
36
+ {
37
+ "name": "Vertical Timezone",
38
+ "props": {
39
+ "startTime": "2026-04-09T20:00:00.000Z",
40
+ "endTime": "2026-04-09T21:30:00.000Z",
41
+ "alignment": "vertical",
42
+ "timezone": true
43
+ }
44
+ }
45
+ ],
46
+ "conditionals": {},
47
+ "hints": {
48
+ "default": {
49
+ "presetName": "Default",
50
+ "message": "Default renders a start and end Date as an inline time range.",
51
+ "type": "info"
52
+ },
53
+ "compact": {
54
+ "presetName": "Compact",
55
+ "message": "Compact switches size to xs for denser layouts.",
56
+ "type": "info"
57
+ },
58
+ "with_icon": {
59
+ "presetName": "With Icon",
60
+ "message": "With Icon adds the clock icon before the range.",
61
+ "type": "info"
62
+ },
63
+ "vertical_timezone": {
64
+ "presetName": "Vertical Timezone",
65
+ "message": "Vertical Timezone stacks the range and includes the timezone label.",
66
+ "type": "info"
67
+ }
68
+ }
69
+ }
@@ -9,14 +9,14 @@
9
9
  "name": "Content",
10
10
  "props": [
11
11
  "time",
12
- "date",
13
12
  "timeZone"
14
13
  ]
15
14
  },
16
15
  {
17
16
  "name": "Appearance",
18
17
  "props": [
19
- "align"
18
+ "align",
19
+ "dark"
20
20
  ]
21
21
  }
22
22
  ],
@@ -35,20 +35,41 @@
35
35
  }
36
36
  },
37
37
  {
38
- "name": "London",
38
+ "name": "Right aligned",
39
39
  "props": {
40
- "time": 1775748600000,
41
- "timeZone": "Europe/London"
40
+ "time": 1775764800000,
41
+ "align": "right"
42
42
  }
43
43
  },
44
44
  {
45
- "name": "Evening slot",
45
+ "name": "London Time",
46
46
  "props": {
47
- "time": 1775764800000,
48
- "align": "right"
47
+ "time": 1775748600000,
48
+ "timeZone": "Europe/London"
49
49
  }
50
50
  }
51
51
  ],
52
52
  "conditionals": {},
53
- "hints": {}
53
+ "hints": {
54
+ "default": {
55
+ "presetName": "Default",
56
+ "message": "Default renders the time and timezone in a stacked layout.",
57
+ "type": "info"
58
+ },
59
+ "centered": {
60
+ "presetName": "Centered",
61
+ "message": "Centered changes align to center while keeping the same timestamp.",
62
+ "type": "info"
63
+ },
64
+ "right_aligned": {
65
+ "presetName": "Right aligned",
66
+ "message": "Right aligned uses align=\"right\" for end-aligned stacked time displays.",
67
+ "type": "info"
68
+ },
69
+ "london_time": {
70
+ "presetName": "London Time",
71
+ "message": "London Time uses timeZone to render the timestamp in a specific timezone.",
72
+ "type": "info"
73
+ }
74
+ }
54
75
  }