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,4 +1,5 @@
1
1
  import React, { useContext } from "react";
2
+ import { createPortal } from "react-dom";
2
3
  import classnames from "classnames";
3
4
  import {
4
5
  buildAriaProps,
@@ -9,6 +10,7 @@ import {
9
10
  import { globalProps, GlobalProps } from "../../utilities/globalProps";
10
11
 
11
12
  import DropdownContext from "../context";
13
+ import { setFloatingOwnerAttribute } from "../../utilities/floatingPortalHosts";
12
14
 
13
15
  import List from "../../pb_list/_list";
14
16
  import ListItem from "../../pb_list/_list_item";
@@ -42,11 +44,15 @@ const DropdownContainer = (props: DropdownContainerProps) => {
42
44
 
43
45
  const {
44
46
  dropdownContainerRef,
47
+ error,
45
48
  filteredOptions,
46
49
  filterItem,
50
+ floatingOwnerId,
51
+ floatingShellClasses,
47
52
  handleChange,
48
53
  inputRef,
49
54
  isDropDownClosed,
55
+ portalHost,
50
56
  setFocusedOptionIndex,
51
57
  } = useContext(DropdownContext);
52
58
 
@@ -61,15 +67,16 @@ const DropdownContainer = (props: DropdownContainerProps) => {
61
67
  className
62
68
  );
63
69
 
64
- return (
70
+ const inner = (
65
71
  <div {...ariaProps}
66
72
  {...dataProps}
67
73
  {...htmlProps}
68
74
  className={classes}
75
+ data-pb-dropdown-portal={portalHost ? "true" : undefined}
69
76
  id={id}
70
77
  onMouseEnter={() => setFocusedOptionIndex(-1)}
71
78
  ref={dropdownContainerRef}
72
- style={{ position: "absolute"}}
79
+ style={portalHost ? undefined : { position: "absolute"}}
73
80
  >
74
81
  {searchbar && (
75
82
  <TextInput dark={dark}
@@ -106,6 +113,36 @@ const DropdownContainer = (props: DropdownContainerProps) => {
106
113
  </List>
107
114
  </div>
108
115
  );
116
+
117
+ if (portalHost) {
118
+ if (isDropDownClosed) {
119
+ return null;
120
+ }
121
+ return createPortal(
122
+ <div
123
+ className={floatingShellClasses}
124
+ ref={(node) => setFloatingOwnerAttribute(node, floatingOwnerId)}
125
+ >
126
+ <div
127
+ className={classnames("dropdown_wrapper", error && "error")}
128
+ style={{
129
+ background: "transparent",
130
+ border: "none",
131
+ boxShadow: "none",
132
+ margin: 0,
133
+ minHeight: 0,
134
+ padding: 0,
135
+ position: "static",
136
+ }}
137
+ >
138
+ {inner}
139
+ </div>
140
+ </div>,
141
+ portalHost,
142
+ );
143
+ }
144
+
145
+ return inner;
109
146
  };
110
147
 
111
148
  export default DropdownContainer;
@@ -42,6 +42,7 @@ const DropdownOption = (props: DropdownOptionProps) => {
42
42
 
43
43
  const {
44
44
  activeStyle,
45
+ disabled,
45
46
  filteredOptions,
46
47
  filterItem,
47
48
  focusedOptionIndex,
@@ -60,13 +61,17 @@ const DropdownOption = (props: DropdownOptionProps) => {
60
61
  ? selected.some((item) => item.label === option?.label)
61
62
  : (selected as GenericObject)?.label === option?.label;
62
63
 
64
+
65
+ const isOptionDisabled = option?.disabled === true;
66
+ const isDisabled = disabled || isOptionDisabled;
67
+
63
68
  if (!isItemMatchingFilter(option) || (multiSelect && isSelected)) {
64
69
  return null;
65
70
  }
66
71
  const isFocused =
67
72
  focusedOptionIndex >= 0 &&
68
73
  filteredOptions[focusedOptionIndex].label === option?.label;
69
- const focusedClass = isFocused && "focused";
74
+ const focusedClass = isFocused ? "focused" : "";
70
75
 
71
76
  const selectedClass = isSelected ? "selected" : "list";
72
77
 
@@ -87,31 +92,37 @@ const DropdownOption = (props: DropdownOptionProps) => {
87
92
  selectedClass,
88
93
  focusedClass,
89
94
  ),
95
+ isDisabled && "disabled",
90
96
  bgTokenClass,
91
97
  fontTokenClass,
92
98
  globalProps(props),
93
99
  className
94
100
  );
101
+ const optionWrapperClass = classnames(
102
+ "dropdown_option_wrapper",
103
+ isDisabled && "disabled"
104
+ );
95
105
 
96
106
  return (
97
107
  <div
98
108
  {...ariaProps}
99
109
  {...dataProps}
100
110
  {...htmlProps}
111
+ aria-disabled={isDisabled}
101
112
  className={classes}
102
113
  id={id}
103
114
  key={key}
104
- onClick= {() => handleOptionClick(option)}
115
+ onClick={isDisabled ? undefined : () => handleOptionClick(option)}
105
116
  >
106
117
  <ListItem
107
- cursor="pointer"
118
+ cursor={disabled ? "default" : "pointer"}
108
119
  dark={dark}
109
120
  data-name={option?.value}
110
121
  key={option?.label}
111
122
  padding="none"
112
123
  >
113
124
  {children ?
114
- <div className="dropdown_option_wrapper">{children}</div> :
125
+ <div className={optionWrapperClass}>{children}</div> :
115
126
  <Body dark={dark}
116
127
  text={option?.label}
117
128
  />
@@ -46,6 +46,7 @@ const DropdownTrigger = (props: DropdownTriggerProps) => {
46
46
  autocomplete,
47
47
  blankSelection,
48
48
  clearable,
49
+ disabled,
49
50
  error,
50
51
  errorId,
51
52
  filterItem,
@@ -113,6 +114,9 @@ const DropdownTrigger = (props: DropdownTriggerProps) => {
113
114
  const triggerAriaLabel = contextLabel
114
115
  ? (children ? contextLabel : `${contextLabel}, ${defaultDisplayPlaceholder}`)
115
116
  : undefined;
117
+ const disabledTriggerProps = disabled
118
+ ? { "aria-disabled": true, tabIndex: -1 }
119
+ : { tabIndex: 0 };
116
120
 
117
121
  return (
118
122
  <div {...ariaProps}
@@ -128,11 +132,11 @@ const DropdownTrigger = (props: DropdownTriggerProps) => {
128
132
  aria-invalid={!!error}
129
133
  aria-label={triggerAriaLabel}
130
134
  id={selectId}
131
- onClick={() => toggleDropdown()}
132
- onKeyDown= {handleKeyDown}
135
+ onClick={() => !disabled && toggleDropdown()}
136
+ onKeyDown= {(e) => !disabled && handleKeyDown(e)}
133
137
  ref={inputWrapperRef}
134
138
  style={{ display: "inline-block" }}
135
- tabIndex= {0}
139
+ {...disabledTriggerProps}
136
140
  >
137
141
  {children}
138
142
  </div>
@@ -142,15 +146,16 @@ const DropdownTrigger = (props: DropdownTriggerProps) => {
142
146
  align="center"
143
147
  borderRadius="lg"
144
148
  className={triggerWrapperClasses}
145
- cursor={`${autocomplete ? "text" : "pointer"}`}
149
+ cursor={disabled ? "default" : `${autocomplete ? "text" : "pointer"}`}
146
150
  htmlOptions={{
147
151
  "aria-describedby": errorId,
152
+ "aria-disabled": disabled,
148
153
  "aria-invalid": !!error,
149
154
  "aria-label": triggerAriaLabel,
150
155
  id: selectId,
151
- onClick: () => handleWrapperClick(),
152
- onKeyDown: handleKeyDown,
153
- tabIndex: "0",
156
+ onClick: () => !disabled && handleWrapperClick(),
157
+ onKeyDown: (e: React.KeyboardEvent) => !disabled && handleKeyDown(e),
158
+ tabIndex: disabled ? "-1" : "0",
154
159
  ref:inputWrapperRef
155
160
  }}
156
161
  justify="between"
@@ -182,12 +187,14 @@ const DropdownTrigger = (props: DropdownTriggerProps) => {
182
187
  {autocomplete && (
183
188
  <input
184
189
  className="dropdown_input"
190
+ disabled={disabled}
185
191
  onChange={handleChange}
186
192
  onClick={(e) => {
187
193
  e.stopPropagation();// keep the wrapper’s handler from firing
194
+ if (disabled) return;
188
195
  toggleDropdown();
189
196
  }}
190
- onFocus={() => setIsInputFocused(true)}
197
+ onFocus={() => !disabled && setIsInputFocused(true)}
191
198
  onKeyDown={(e) => {
192
199
  handleKeyDown(e);
193
200
  e.stopPropagation(); //Fixes issue with keyboard accessibility
@@ -213,12 +220,14 @@ const DropdownTrigger = (props: DropdownTriggerProps) => {
213
220
  {autocomplete && !multiSelect && (
214
221
  <input
215
222
  className="dropdown_input"
223
+ disabled={disabled}
216
224
  onChange={handleChange}
217
225
  onClick={(e) => {
218
226
  e.stopPropagation();// keep the wrapper’s handler from firing
227
+ if (disabled) return;
219
228
  toggleDropdown();
220
229
  }}
221
- onFocus={() => setIsInputFocused(true)}
230
+ onFocus={() => !disabled && setIsInputFocused(true)}
222
231
  onKeyDown={handleKeyDown}
223
232
  placeholder={
224
233
  joinedLabels
@@ -239,16 +248,16 @@ const DropdownTrigger = (props: DropdownTriggerProps) => {
239
248
  dark={dark}
240
249
  display="flex"
241
250
  htmlOptions={{
242
- onClick: (e: Event) => {e.stopPropagation();handleWrapperClick()}
251
+ onClick: (e: Event) => {e.stopPropagation(); !disabled && handleWrapperClick()}
243
252
  }}
244
253
  key={`${isDropDownClosed ? "chevron-down" : "chevron-up"}`}
245
254
  >
246
255
  {(!blankSelection || selected?.value !== optionsWithBlankSelection?.[0]?.value) && (
247
256
  <>
248
257
  {clearable !== false && selectedArray.length > 0 && (
249
- <div onClick={(e)=>{e.stopPropagation();handleBackspace()}}>
258
+ <div onClick={(e)=>{e.stopPropagation(); !disabled && handleBackspace()}}>
250
259
  <Icon
251
- cursor="pointer"
260
+ cursor={disabled ? "default" : "pointer"}
252
261
  dark={dark}
253
262
  icon="times"
254
263
  paddingRight="xs"
@@ -259,7 +268,7 @@ const DropdownTrigger = (props: DropdownTriggerProps) => {
259
268
  </>
260
269
  )}
261
270
  <Icon
262
- cursor="pointer"
271
+ cursor={disabled ? "default" : "pointer"}
263
272
  dark={dark}
264
273
  icon={`${isDropDownClosed ? "chevron-down" : "chevron-up"}`}
265
274
  size="sm"
@@ -0,0 +1,66 @@
1
+ <div id="file-upload-remove-replace">
2
+ <%= pb_rails("list", props: { id: "selected-files-list", margin_bottom: "sm" }) %>
3
+
4
+ <%= pb_rails("file_upload", props: {
5
+ id: "remove_replace",
6
+ input_options: { multiple: true },
7
+ }) %>
8
+ </div>
9
+
10
+ <template id="file-list-item-template">
11
+ <%= pb_rails("list/item") do %>
12
+ <%= pb_rails("flex", props: { align: "center", justify: "between", width: "100%" }) do %>
13
+ <%= pb_rails("body", props: { data: { file_name: true } }) %>
14
+ <%= pb_rails("circle_icon_button", props: {
15
+ icon: "times",
16
+ variant: "secondary",
17
+ input_options: { classname: "remove-file-button" },
18
+ }) %>
19
+ <% end %>
20
+ <% end %>
21
+ </template>
22
+
23
+ <%= javascript_tag defer: "defer" do %>
24
+ document.addEventListener("DOMContentLoaded", function () {
25
+ const fileInput = document.getElementById("upload-remove_replace")
26
+ const list = document.getElementById("selected-files-list")
27
+ const template = document.getElementById("file-list-item-template")
28
+ let files = []
29
+
30
+ if (!fileInput || !list || !template) return
31
+
32
+ function syncInput() {
33
+ const dataTransfer = new DataTransfer()
34
+ files.forEach((file) => dataTransfer.items.add(file))
35
+ fileInput.files = dataTransfer.files
36
+ }
37
+
38
+ function render() {
39
+ list.innerHTML = ""
40
+
41
+ files.forEach((file, index) => {
42
+ const clone = template.content.cloneNode(true)
43
+ const nameElement = clone.querySelector("[data-file-name]")
44
+ const removeButton = clone.querySelector(".remove-file-button")
45
+
46
+ nameElement.textContent = file.name
47
+ removeButton.addEventListener("click", function (event) {
48
+ event.preventDefault()
49
+ event.stopPropagation()
50
+ files = files.filter((_, fileIndex) => fileIndex !== index)
51
+ syncInput()
52
+ render()
53
+ })
54
+
55
+ list.appendChild(clone)
56
+ })
57
+ }
58
+
59
+ fileInput.addEventListener("change", function () {
60
+ const newFiles = Array.from(fileInput.files)
61
+ files = [...files, ...newFiles]
62
+ syncInput()
63
+ render()
64
+ })
65
+ })
66
+ <% end %>
@@ -0,0 +1,53 @@
1
+
2
+ import React, { useState } from 'react'
3
+
4
+ import Body from '../../pb_body/_body'
5
+ import CircleIconButton from '../../pb_circle_icon_button/_circle_icon_button'
6
+ import FileUpload from '../../pb_file_upload/_file_upload'
7
+ import Flex from '../../pb_flex/_flex'
8
+ import List from '../../pb_list/_list'
9
+ import ListItem from '../../pb_list/_list_item'
10
+
11
+ const FileUploadRemoveReplace = (props) => {
12
+ const [filesToUpload, setFilesToUpload] = useState([])
13
+
14
+ const handleOnFilesAccepted = (files) => {
15
+ setFilesToUpload([...filesToUpload, ...files])
16
+ }
17
+
18
+ const handleRemoveFile = (index) => {
19
+ setFilesToUpload(filesToUpload.filter((_, fileIndex) => fileIndex !== index))
20
+ }
21
+
22
+ return (
23
+ <div>
24
+ {filesToUpload.length > 0 && (
25
+ <List marginBottom="sm">
26
+ {filesToUpload.map((file, index) => (
27
+ <ListItem key={`${file.name}-${index}`}>
28
+ <Flex
29
+ align="center"
30
+ justify="between"
31
+ width="100%"
32
+ >
33
+ <Body text={file.name} />
34
+ <CircleIconButton
35
+ aria={{ label: `Remove ${file.name}` }}
36
+ icon="times"
37
+ onClick={() => handleRemoveFile(index)}
38
+ variant="secondary"
39
+ />
40
+ </Flex>
41
+ </ListItem>
42
+ ))}
43
+ </List>
44
+ )}
45
+ <FileUpload
46
+ onFilesAccepted={handleOnFilesAccepted}
47
+ {...props}
48
+ />
49
+ </div>
50
+ )
51
+ }
52
+
53
+ export default FileUploadRemoveReplace
@@ -0,0 +1,5 @@
1
+ The File Upload kit does not include built-in remove or replace behavior. Manage selected files in application state and compose the kit with other Playbook components.
2
+
3
+ **Remove** — Track accepted files in state and filter out the file to remove. In React, pair `List` with `CircleIconButton`. In Rails, listen for `change` on the file input, keep files in a JavaScript array, and use `DataTransfer` to sync the input when a file is removed.
4
+
5
+ **Replace** — Selecting a new file on the native Rails input replaces the current selection. For single-file React workflows, set state to the newly accepted files instead of appending: `setFilesToUpload(files)`.
@@ -2,7 +2,8 @@
2
2
  "template": "<FileUpload{{props}} />",
3
3
  "propTargets": {},
4
4
  "defaults": {
5
- "accept": {}
5
+ "accept": {},
6
+ "dark": false
6
7
  },
7
8
  "groups": [
8
9
  {
@@ -4,6 +4,7 @@ examples:
4
4
  - file_upload_default: File Upload
5
5
  - file_upload_custom: Custom
6
6
  - file_upload_error: Error
7
+ - file_upload_remove_replace: Remove and Replace
7
8
 
8
9
  react:
9
10
  - file_upload_default: Default List of files to upload
@@ -11,4 +12,5 @@ examples:
11
12
  - file_upload_custom_message: Add a custom message
12
13
  - file_upload_custom_description: Add your one accepted files description
13
14
  - file_upload_max_size: Set a file size limit
14
- - file_upload_error: Error
15
+ - file_upload_error: Error
16
+ - file_upload_remove_replace: Remove and Replace
@@ -4,3 +4,4 @@ export { default as FileUploadCustomMessage } from './_file_upload_custom_messag
4
4
  export { default as FileUploadCustomDescription } from './_file_upload_custom_description.jsx'
5
5
  export { default as FileUploadMaxSize } from './_file_upload_max_size.jsx'
6
6
  export { default as FileUploadError } from './_file_upload_error.jsx'
7
+ export { default as FileUploadRemoveReplace } from './_file_upload_remove_replace.jsx'
@@ -8,7 +8,7 @@
8
8
  ],
9
9
  "props": {
10
10
  "accept": {
11
- "type": "Record<string, string[]>",
11
+ "type": "GenericObject",
12
12
  "platforms": [
13
13
  "react",
14
14
  "rails"
@@ -40,7 +40,7 @@
40
40
  ]
41
41
  },
42
42
  "onFilesAccepted": {
43
- "type": "Callback<File, File>",
43
+ "type": "function",
44
44
  "platforms": [
45
45
  "react"
46
46
  ]
@@ -113,7 +113,7 @@
113
113
  "platforms": [
114
114
  "rails"
115
115
  ],
116
- "type": "string"
116
+ "type": "GenericObject"
117
117
  }
118
118
  },
119
119
  "globalProps": true,
@@ -1,22 +1,32 @@
1
- import React from 'react'
1
+ import React, { useEffect } from 'react'
2
2
  import { isEmpty, omitBy, map } from '../../utilities/object'
3
3
 
4
4
  import Body from '../../pb_body/_body'
5
5
  import Caption from '../../pb_caption/_caption'
6
6
  import Title from '../../pb_title/_title'
7
+ import InteractiveFilter, { InteractiveFilterConfig } from './InteractiveFilter'
7
8
 
8
9
  export type FilterDescription = {
9
10
  [key: string]: string | null | boolean,
10
11
  }
11
12
 
13
+ export type InteractiveFilters = {
14
+ [key: string]: InteractiveFilterConfig,
15
+ }
16
+
12
17
  export type CurrentFiltersProps = {
13
18
  dark: boolean,
14
19
  filters: FilterDescription,
20
+ interactiveFilters?: InteractiveFilters,
15
21
  }
16
22
 
17
23
  const hiddenFilters = (value: any) => isEmpty(value) && value !== true
18
24
 
19
- const CurrentFilters = ({ dark, filters }: CurrentFiltersProps): React.ReactElement => {
25
+ const CurrentFilters = ({
26
+ dark,
27
+ filters,
28
+ interactiveFilters = {},
29
+ }: CurrentFiltersProps): React.ReactElement => {
20
30
  const displayableFilters = omitBy(filters, hiddenFilters)
21
31
 
22
32
  return (
@@ -35,33 +45,50 @@ const CurrentFilters = ({ dark, filters }: CurrentFiltersProps): React.ReactElem
35
45
  { !isEmpty(filters) &&
36
46
  <div className="filters">
37
47
  <div className="left_gradient" />
38
- {map(displayableFilters, (value, name) => (
39
- <div
40
- className="filter"
41
- key={`filter-${name}`}
42
- >
43
- { value === true ?
44
- <Title
45
- dark={dark}
46
- size={4}
47
- tag="h4"
48
- text={`${name}`}
49
- /> :
50
- <div>
51
- <Caption
52
- dark={dark}
53
- text={`${name}`}
54
- />
55
- <Title
56
- dark={dark}
57
- size={4}
58
- tag="h4"
59
- text={value}
60
- />
48
+ {map(displayableFilters, (value, name) => {
49
+ const interactiveConfig = interactiveFilters[name]
50
+ return (
51
+ <div
52
+ className={`filter${interactiveConfig ? ' interactive' : ''}`}
53
+ key={`filter-${name}`}
54
+ >
55
+ { interactiveConfig ?
56
+ <InteractiveFilter
57
+ config={interactiveConfig}
58
+ dark={dark}
59
+ editorValue={interactiveConfig.editorValue}
60
+ name={String(name)}
61
+ value={
62
+ interactiveConfig.value !== undefined
63
+ ? interactiveConfig.value
64
+ : value === true
65
+ ? ''
66
+ : (value as string)
67
+ }
68
+ /> :
69
+ value === true ?
70
+ <Title
71
+ dark={dark}
72
+ size={4}
73
+ tag="h4"
74
+ text={`${name}`}
75
+ /> :
76
+ <div>
77
+ <Caption
78
+ dark={dark}
79
+ text={`${name}`}
80
+ />
81
+ <Title
82
+ dark={dark}
83
+ size={4}
84
+ tag="h4"
85
+ text={value}
86
+ />
87
+ </div>
88
+ }
61
89
  </div>
62
- }
63
- </div>
64
- ))}
90
+ )
91
+ })}
65
92
  <div className="right_gradient" />
66
93
  </div>
67
94
  }
@@ -1,6 +1,6 @@
1
1
  import React from 'react'
2
2
 
3
- import CurrentFilters, { FilterDescription } from './CurrentFilters'
3
+ import CurrentFilters, { FilterDescription, InteractiveFilters } from './CurrentFilters'
4
4
  import FilterBackground, { FilterBackgroundProps } from './FilterBackground'
5
5
  import FiltersPopover from './FiltersPopover'
6
6
  import ResultsCount from './ResultsCount'
@@ -17,6 +17,7 @@ import SectionSeparator from '../../pb_section_separator/_section_separator'
17
17
  export type FilterDoubleProps = {
18
18
  children?: React.ReactChild[] | React.ReactChild,
19
19
  filters?: FilterDescription,
20
+ interactiveFilters?: InteractiveFilters,
20
21
  onSortChange?: SortingChangeCallback,
21
22
  results?: number,
22
23
  sortOptions?: SortOptions,
@@ -28,6 +29,7 @@ const FilterDouble = ({
28
29
  sortOptions,
29
30
  sortValue,
30
31
  filters,
32
+ interactiveFilters,
31
33
  results,
32
34
  children,
33
35
  dark,
@@ -57,6 +59,7 @@ const FilterDouble = ({
57
59
  <CurrentFilters
58
60
  dark={dark}
59
61
  filters={filters}
62
+ interactiveFilters={interactiveFilters}
60
63
  />
61
64
  </Flex>
62
65
  <SectionSeparator dark={dark} />
@@ -3,7 +3,7 @@ import { isEmpty } from '../../utilities/object'
3
3
 
4
4
  import Flex from '../../pb_flex/_flex'
5
5
 
6
- import CurrentFilters, { FilterDescription } from './CurrentFilters'
6
+ import CurrentFilters, { FilterDescription, InteractiveFilters } from './CurrentFilters'
7
7
  import FilterBackground, { FilterBackgroundProps } from './FilterBackground'
8
8
  import FiltersPopover from './FiltersPopover'
9
9
  import ResultsCount from './ResultsCount'
@@ -16,6 +16,7 @@ import SortMenu, {
16
16
  export type FilterSingleProps = {
17
17
  children?: React.ReactChild[] | React.ReactChild,
18
18
  filters?: FilterDescription,
19
+ interactiveFilters?: InteractiveFilters,
19
20
  onSortChange?: SortingChangeCallback,
20
21
  results?: number,
21
22
  sortOptions?: SortOptions,
@@ -27,6 +28,7 @@ const FilterSingle = ({
27
28
  sortOptions,
28
29
  sortValue,
29
30
  filters,
31
+ interactiveFilters,
30
32
  results,
31
33
  children,
32
34
  dark,
@@ -60,6 +62,7 @@ const FilterSingle = ({
60
62
  <CurrentFilters
61
63
  dark={dark}
62
64
  filters={filters}
65
+ interactiveFilters={interactiveFilters}
63
66
  />
64
67
  </>
65
68
  }