playbook_ui 16.10.0.pre.alpha.PLAY3032dropdowndisabledinput17361 → 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 (187) 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 +19 -6
  4. data/app/pb_kits/playbook/pb_advanced_table/Hooks/useTableState.ts +17 -12
  5. data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.scss +3 -0
  6. data/app/pb_kits/playbook/pb_advanced_table/advanced_table.test.jsx +26 -1
  7. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_pinned_rows.jsx +19 -2
  8. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_pinned_rows_react.md +2 -2
  9. data/app/pb_kits/playbook/pb_advanced_table/docs/example.yml +0 -1
  10. data/app/pb_kits/playbook/pb_checkbox/kit.schema.json +1 -1
  11. data/app/pb_kits/playbook/pb_circle_icon_button/kit.schema.json +1 -1
  12. data/app/pb_kits/playbook/pb_date_picker/_date_picker.scss +6 -0
  13. data/app/pb_kits/playbook/pb_date_picker/_date_picker.tsx +16 -2
  14. data/app/pb_kits/playbook/pb_date_picker/date_picker.html.erb +58 -1
  15. data/app/pb_kits/playbook/pb_date_picker/date_picker_helper.ts +310 -64
  16. data/app/pb_kits/playbook/pb_date_time/kit.schema.json +1 -1
  17. data/app/pb_kits/playbook/pb_date_time_stacked/kit.schema.json +1 -1
  18. data/app/pb_kits/playbook/pb_dialog/_dialog.scss +54 -1
  19. data/app/pb_kits/playbook/pb_dialog/_dialog.tsx +21 -5
  20. data/app/pb_kits/playbook/pb_dialog/_dialog_context.tsx +8 -2
  21. data/app/pb_kits/playbook/pb_dialog/child_kits/_dialog_header.tsx +1 -1
  22. data/app/pb_kits/playbook/pb_dialog/dialog.html.erb +5 -1
  23. data/app/pb_kits/playbook/pb_dialog/dialog.test.jsx +125 -0
  24. data/app/pb_kits/playbook/pb_dialog/index.js +11 -1
  25. data/app/pb_kits/playbook/pb_dropdown/_dropdown.scss +90 -0
  26. data/app/pb_kits/playbook/pb_dropdown/_dropdown.tsx +101 -31
  27. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_custom_display_disabled_option.html.erb +93 -0
  28. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_custom_display_disabled_option.jsx +127 -0
  29. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_custom_display_disabled_option.md +1 -0
  30. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_disabled_option.html.erb +10 -0
  31. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_disabled_option.jsx +37 -0
  32. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_disabled_option.md +1 -0
  33. data/app/pb_kits/playbook/pb_dropdown/docs/_playground.json +149 -237
  34. data/app/pb_kits/playbook/pb_dropdown/docs/_playground.overrides.json +58 -74
  35. data/app/pb_kits/playbook/pb_dropdown/docs/example.yml +4 -0
  36. data/app/pb_kits/playbook/pb_dropdown/docs/index.js +2 -0
  37. data/app/pb_kits/playbook/pb_dropdown/dropdown.test.jsx +40 -0
  38. data/app/pb_kits/playbook/pb_dropdown/dropdown_option.html.erb +2 -2
  39. data/app/pb_kits/playbook/pb_dropdown/dropdown_option.rb +27 -2
  40. data/app/pb_kits/playbook/pb_dropdown/hooks/useHandleOnKeydown.tsx +25 -5
  41. data/app/pb_kits/playbook/pb_dropdown/index.js +225 -25
  42. data/app/pb_kits/playbook/pb_dropdown/keyboard_accessibility.js +13 -10
  43. data/app/pb_kits/playbook/pb_dropdown/subcomponents/DropdownContainer.tsx +39 -2
  44. data/app/pb_kits/playbook/pb_dropdown/subcomponents/DropdownOption.tsx +13 -3
  45. data/app/pb_kits/playbook/pb_file_upload/docs/_file_upload_remove_replace.html.erb +66 -0
  46. data/app/pb_kits/playbook/pb_file_upload/docs/_file_upload_remove_replace.jsx +53 -0
  47. data/app/pb_kits/playbook/pb_file_upload/docs/_file_upload_remove_replace.md +5 -0
  48. data/app/pb_kits/playbook/pb_file_upload/docs/example.yml +3 -1
  49. data/app/pb_kits/playbook/pb_file_upload/docs/index.js +1 -0
  50. data/app/pb_kits/playbook/pb_file_upload/kit.schema.json +1 -1
  51. data/app/pb_kits/playbook/pb_form_group/docs/_playground.json +100 -1
  52. data/app/pb_kits/playbook/pb_form_group/docs/_playground.overrides.json +91 -0
  53. data/app/pb_kits/playbook/pb_full_screen/_full_screen.scss +77 -0
  54. data/app/pb_kits/playbook/pb_full_screen/_full_screen.tsx +183 -0
  55. data/app/pb_kits/playbook/pb_full_screen/docs/_description.md +1 -0
  56. data/app/pb_kits/playbook/pb_full_screen/docs/_full_screen_content_padding.jsx +68 -0
  57. data/app/pb_kits/playbook/pb_full_screen/docs/_full_screen_content_padding.md +1 -0
  58. data/app/pb_kits/playbook/pb_full_screen/docs/_full_screen_custom_trigger.jsx +71 -0
  59. data/app/pb_kits/playbook/pb_full_screen/docs/_full_screen_custom_trigger.md +1 -0
  60. data/app/pb_kits/playbook/pb_full_screen/docs/_full_screen_default.html.erb +3 -0
  61. data/app/pb_kits/playbook/pb_full_screen/docs/_full_screen_default.jsx +63 -0
  62. data/app/pb_kits/playbook/pb_full_screen/docs/_full_screen_default.md +1 -0
  63. data/app/pb_kits/playbook/pb_full_screen/docs/_full_screen_header_text_styling.jsx +68 -0
  64. data/app/pb_kits/playbook/pb_full_screen/docs/_full_screen_header_text_styling.md +1 -0
  65. data/app/pb_kits/playbook/pb_full_screen/docs/_full_screen_sticky_header.jsx +68 -0
  66. data/app/pb_kits/playbook/pb_full_screen/docs/_full_screen_sticky_header.md +1 -0
  67. data/app/pb_kits/playbook/pb_full_screen/docs/_full_screen_table_and_filter.jsx +149 -0
  68. data/app/pb_kits/playbook/pb_full_screen/docs/_full_screen_table_and_filter.md +1 -0
  69. data/app/pb_kits/playbook/pb_full_screen/docs/_playground.json +155 -0
  70. data/app/pb_kits/playbook/pb_full_screen/docs/_playground.overrides.json +137 -0
  71. data/app/pb_kits/playbook/pb_full_screen/docs/example.yml +14 -0
  72. data/app/pb_kits/playbook/pb_full_screen/docs/index.js +6 -0
  73. data/app/pb_kits/playbook/pb_full_screen/full_screen.html.erb +12 -0
  74. data/app/pb_kits/playbook/pb_full_screen/full_screen.rb +11 -0
  75. data/app/pb_kits/playbook/pb_full_screen/full_screen.test.jsx +237 -0
  76. data/app/pb_kits/playbook/pb_full_screen/kit.schema.json +89 -0
  77. data/app/pb_kits/playbook/pb_full_screen/useFullScreen.ts +15 -0
  78. data/app/pb_kits/playbook/pb_icon/_icon.tsx +22 -11
  79. data/app/pb_kits/playbook/pb_icon/docs/_playground.json +2 -16
  80. data/app/pb_kits/playbook/pb_icon/docs/_playground.overrides.json +2 -13
  81. data/app/pb_kits/playbook/pb_icon/icon.rb +5 -2
  82. data/app/pb_kits/playbook/pb_icon/kit.schema.json +3 -5
  83. data/app/pb_kits/playbook/pb_layout/docs/_playground.json +246 -1
  84. data/app/pb_kits/playbook/pb_layout/docs/_playground.overrides.json +188 -0
  85. data/app/pb_kits/playbook/pb_multi_level_select/_multi_level_select.scss +7 -7
  86. data/app/pb_kits/playbook/pb_multi_level_select/_multi_level_select.tsx +125 -10
  87. data/app/pb_kits/playbook/pb_popover/_popover.scss +27 -0
  88. data/app/pb_kits/playbook/pb_popover/_popover.tsx +49 -16
  89. data/app/pb_kits/playbook/pb_popover/index.ts +35 -4
  90. data/app/pb_kits/playbook/pb_popover/popover.html.erb +5 -2
  91. data/app/pb_kits/playbook/pb_popover/popover.test.js +212 -5
  92. data/app/pb_kits/playbook/pb_progress_pills/docs/_playground.json +26 -13
  93. data/app/pb_kits/playbook/pb_progress_pills/docs/_playground.overrides.json +24 -6
  94. data/app/pb_kits/playbook/pb_progress_simple/docs/_playground.json +50 -17
  95. data/app/pb_kits/playbook/pb_progress_simple/docs/_playground.overrides.json +41 -7
  96. data/app/pb_kits/playbook/pb_progress_step/docs/_playground.json +218 -1
  97. data/app/pb_kits/playbook/pb_progress_step/docs/_playground.overrides.json +189 -0
  98. data/app/pb_kits/playbook/pb_radio/docs/_playground.json +80 -6
  99. data/app/pb_kits/playbook/pb_radio/docs/_playground.overrides.json +82 -3
  100. data/app/pb_kits/playbook/pb_radio/kit.schema.json +1 -1
  101. data/app/pb_kits/playbook/pb_rich_text_editor/docs/_playground.json +171 -1
  102. data/app/pb_kits/playbook/pb_rich_text_editor/docs/_playground.overrides.json +153 -0
  103. data/app/pb_kits/playbook/pb_select/docs/_playground.json +65 -19
  104. data/app/pb_kits/playbook/pb_select/docs/_playground.overrides.json +54 -14
  105. data/app/pb_kits/playbook/pb_select/kit.schema.json +1 -1
  106. data/app/pb_kits/playbook/pb_selectable_card/docs/_playground.json +75 -82
  107. data/app/pb_kits/playbook/pb_selectable_card/docs/_playground.overrides.json +76 -76
  108. data/app/pb_kits/playbook/pb_selectable_card/kit.schema.json +1 -1
  109. data/app/pb_kits/playbook/pb_selectable_card_icon/docs/_playground.json +128 -1
  110. data/app/pb_kits/playbook/pb_selectable_card_icon/docs/_playground.overrides.json +106 -0
  111. data/app/pb_kits/playbook/pb_selectable_card_icon/kit.schema.json +1 -1
  112. data/app/pb_kits/playbook/pb_selectable_icon/docs/_playground.json +37 -21
  113. data/app/pb_kits/playbook/pb_selectable_icon/docs/_playground.overrides.json +35 -18
  114. data/app/pb_kits/playbook/pb_selectable_icon/kit.schema.json +1 -1
  115. data/app/pb_kits/playbook/pb_selectable_list/docs/_playground.json +174 -12
  116. data/app/pb_kits/playbook/pb_selectable_list/docs/_playground.overrides.json +162 -10
  117. data/app/pb_kits/playbook/pb_skeleton_loading/docs/_playground.json +92 -1
  118. data/app/pb_kits/playbook/pb_skeleton_loading/docs/_playground.overrides.json +80 -0
  119. data/app/pb_kits/playbook/pb_source/docs/_playground.json +88 -1
  120. data/app/pb_kits/playbook/pb_source/docs/_playground.overrides.json +80 -0
  121. data/app/pb_kits/playbook/pb_star_rating/docs/_playground.json +28 -53
  122. data/app/pb_kits/playbook/pb_star_rating/docs/_playground.overrides.json +33 -32
  123. data/app/pb_kits/playbook/pb_star_rating/kit.schema.json +1 -1
  124. data/app/pb_kits/playbook/pb_stat_change/docs/_playground.json +15 -9
  125. data/app/pb_kits/playbook/pb_stat_change/docs/_playground.overrides.json +15 -5
  126. data/app/pb_kits/playbook/pb_stat_value/docs/_playground.json +19 -9
  127. data/app/pb_kits/playbook/pb_stat_value/docs/_playground.overrides.json +18 -7
  128. data/app/pb_kits/playbook/pb_stat_value/kit.schema.json +1 -1
  129. data/app/pb_kits/playbook/pb_table/docs/_playground.json +259 -1
  130. data/app/pb_kits/playbook/pb_table/docs/_playground.overrides.json +176 -0
  131. data/app/pb_kits/playbook/pb_text_input/docs/_playground.json +44 -5
  132. data/app/pb_kits/playbook/pb_text_input/docs/_playground.overrides.json +39 -3
  133. data/app/pb_kits/playbook/pb_text_input/kit.schema.json +2 -2
  134. data/app/pb_kits/playbook/pb_textarea/docs/_playground.json +35 -3
  135. data/app/pb_kits/playbook/pb_textarea/docs/_playground.overrides.json +28 -3
  136. data/app/pb_kits/playbook/pb_time/docs/_playground.json +28 -14
  137. data/app/pb_kits/playbook/pb_time/docs/_playground.overrides.json +26 -13
  138. data/app/pb_kits/playbook/pb_time_picker/_time_picker.scss +42 -0
  139. data/app/pb_kits/playbook/pb_time_picker/_time_picker.tsx +309 -167
  140. data/app/pb_kits/playbook/pb_time_picker/docs/_playground.json +36 -30
  141. data/app/pb_kits/playbook/pb_time_picker/docs/_playground.overrides.json +31 -26
  142. data/app/pb_kits/playbook/pb_time_picker/index.ts +263 -11
  143. data/app/pb_kits/playbook/pb_time_range_inline/docs/_playground.json +86 -1
  144. data/app/pb_kits/playbook/pb_time_range_inline/docs/_playground.overrides.json +69 -0
  145. data/app/pb_kits/playbook/pb_time_stacked/docs/_playground.json +30 -9
  146. data/app/pb_kits/playbook/pb_time_stacked/docs/_playground.overrides.json +30 -9
  147. data/app/pb_kits/playbook/pb_timeline/docs/_playground.json +199 -1
  148. data/app/pb_kits/playbook/pb_timeline/docs/_playground.overrides.json +165 -0
  149. data/app/pb_kits/playbook/pb_timestamp/docs/_playground.json +36 -21
  150. data/app/pb_kits/playbook/pb_timestamp/docs/_playground.overrides.json +35 -20
  151. data/app/pb_kits/playbook/pb_toggle/docs/_playground.json +24 -13
  152. data/app/pb_kits/playbook/pb_toggle/docs/_playground.overrides.json +20 -12
  153. data/app/pb_kits/playbook/pb_toggle/kit.schema.json +1 -1
  154. data/app/pb_kits/playbook/pb_tooltip/docs/_playground.json +42 -23
  155. data/app/pb_kits/playbook/pb_tooltip/docs/_playground.overrides.json +35 -15
  156. data/app/pb_kits/playbook/pb_typeahead/_typeahead.tsx +109 -3
  157. data/app/pb_kits/playbook/pb_typeahead/docs/_playground.json +124 -44
  158. data/app/pb_kits/playbook/pb_typeahead/docs/_playground.overrides.json +98 -31
  159. data/app/pb_kits/playbook/pb_typeahead/kit.schema.json +7 -1
  160. data/app/pb_kits/playbook/pb_user/docs/_playground.json +33 -15
  161. data/app/pb_kits/playbook/pb_user/docs/_playground.overrides.json +32 -15
  162. data/app/pb_kits/playbook/pb_user_badge/docs/_playground.json +26 -12
  163. data/app/pb_kits/playbook/pb_user_badge/docs/_playground.overrides.json +26 -9
  164. data/app/pb_kits/playbook/pb_weekday_stacked/docs/_playground.json +32 -5
  165. data/app/pb_kits/playbook/pb_weekday_stacked/docs/_playground.overrides.json +30 -4
  166. data/app/pb_kits/playbook/utilities/_border.scss +262 -0
  167. data/app/pb_kits/playbook/utilities/floatingPortalHosts.ts +565 -0
  168. data/app/pb_kits/playbook/utilities/global-props.schema.json +98 -0
  169. data/app/pb_kits/playbook/utilities/globalProps.ts +83 -1
  170. data/app/pb_kits/playbook/utilities/test/globalProps/border.test.js +66 -0
  171. data/dist/chunks/{_pb_line_graph-DYysA_-M.js → _pb_line_graph-C2H9vs_8.js} +1 -1
  172. data/dist/chunks/_typeahead-Du8dRYaM.js +5 -0
  173. data/dist/chunks/globalProps-DIAZ03-L.js +6 -0
  174. data/dist/chunks/{lib-BQnni8Yf.js → lib-ZHDedNfP.js} +2 -2
  175. data/dist/chunks/vendor.js +5 -5
  176. data/dist/menu.yml +7 -0
  177. data/dist/playbook-rails-react-bindings.js +1 -1
  178. data/dist/playbook-rails.js +1 -1
  179. data/dist/playbook.css +1 -1
  180. data/lib/playbook/border.rb +87 -0
  181. data/lib/playbook/classnames.rb +1 -0
  182. data/lib/playbook/kit_base.rb +2 -0
  183. data/lib/playbook/pb_forms_global_props_helper.rb +15 -0
  184. data/lib/playbook/version.rb +1 -1
  185. metadata +54 -6
  186. data/dist/chunks/_typeahead-B0yIrn2R.js +0 -5
  187. data/dist/chunks/globalProps-CC-0LNvd.js +0 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3c7de1ce3d86ce191ea5196d520df0aeb0919a9802462e6d1ac2c2f5f92eaa38
4
- data.tar.gz: 36ebe37441e50aa17346ddc906a3492cfd076fd19bc9f474481e16e37df895ac
3
+ metadata.gz: 47abbd6021f5f2e78c6eec2c21e748448cbdc2a3b5699f97914e9dec865836ea
4
+ data.tar.gz: 1e3542fd598d4209193fc2f6f1357d06ab1fffcb17fef11b0d84aa322663fb7b
5
5
  SHA512:
6
- metadata.gz: 8463caa5d2ee1372d2964109e908da03cbb433d81b6de5af078d24ba33a904c9642f9bdb9051be0e7e7e98c4f1732a768f01235112a7f6ab2e4e96a88726ae56
7
- data.tar.gz: 9b1c86838e5edcf56d3714ccb7c03ae0dee950be56052f56a4e1eb695dc30db0ce59b52b544fbf6df5965ae487f16669084bb3fb7c6070063d48fe6ffdb96588
6
+ metadata.gz: '02951b7c75b1fc99bffa8893be7def930da61e5f98f1ecda05df882085a94ce56b07ba45131f0fe96f8e14b48db98d5ae414c68de8f05b439396d4735c743b00'
7
+ data.tar.gz: ab82942a91594a7e180f52942659480309c98210bce7cb630a7ca8308f3dad9ca977859088147cfc039716362af2af0dc18f4fe8c5fd2f064c55b3d15a9f3ca4
@@ -36,6 +36,7 @@
36
36
  @import 'pb_form/form';
37
37
  @import 'pb_form_group/form_group';
38
38
  @import 'pb_form_pill/form_pill';
39
+ @import 'pb_full_screen/full_screen';
39
40
  @import 'pb_hashtag/hashtag';
40
41
  @import 'pb_highlight/highlight';
41
42
  @import 'pb_home_address_street/home_address_street';
@@ -128,3 +129,4 @@
128
129
  @import 'utilities/vertical_align';
129
130
  @import 'utilities/height';
130
131
  @import 'utilities/gap';
132
+ @import 'utilities/border';
@@ -162,20 +162,26 @@ export const RegularTableView = ({
162
162
  );
163
163
 
164
164
  // Row pinning
165
- function PinnedRow({ row }: { row: Row<any> }) {
165
+ function PinnedRow({ row, position }: { row: Row<any>; position: 'top' | 'bottom' }) {
166
166
  const customRowStyle = getRowStyle(rowStyling, row);
167
+ const bottomRowsCount = table.getBottomRows().length;
168
+
167
169
  return (
168
170
  <tr
169
- className={classnames(
170
- `pinned-row`,
171
- )}
171
+ className={classnames('pinned-row', {
172
+ 'pinned-row-bottom': position === 'bottom',
173
+ })}
172
174
  style={{
173
175
  backgroundColor: customRowStyle?.backgroundColor ? customRowStyle?.backgroundColor : 'white',
174
176
  color: customRowStyle?.fontColor,
175
177
  position: 'sticky',
176
178
  top:
177
- row.getIsPinned() === 'top'
178
- ? `${row.getPinnedIndex() * rowHeight + headerHeight + actionBarHeight}px`
179
+ position === 'top'
180
+ ? `${row.getPinnedIndex() * rowHeight + headerHeight + actionBarHeight}px`
181
+ : undefined,
182
+ bottom:
183
+ position === 'bottom'
184
+ ? `${(bottomRowsCount - 1 - row.getPinnedIndex()) * rowHeight}px`
179
185
  : undefined,
180
186
  zIndex: '3',
181
187
  fontWeight: getFontWeight(customRowStyle),
@@ -201,6 +207,7 @@ export const RegularTableView = ({
201
207
  <>
202
208
  {pinnedRows && table.getTopRows().map((row: Row<GenericObject>) => (
203
209
  <PinnedRow key={row.id}
210
+ position="top"
204
211
  row={row}
205
212
  />
206
213
  ))}
@@ -274,6 +281,12 @@ export const RegularTableView = ({
274
281
  </React.Fragment>
275
282
  );
276
283
  })}
284
+ {pinnedRows && table.getBottomRows().map((row: Row<GenericObject>) => (
285
+ <PinnedRow key={row.id}
286
+ position="bottom"
287
+ row={row}
288
+ />
289
+ ))}
277
290
  </>
278
291
  );
279
292
  }
@@ -72,6 +72,7 @@ export function useTableState({
72
72
  const [localColumnVisibility, setLocalColumnVisibility] = useState({});
73
73
  const [localRowPinning, setLocalRowPinning] = useState<RowPinningState>({
74
74
  top: [],
75
+ bottom: [],
75
76
  });
76
77
  // Manage local state to preserve current page index when inlineRowLoading is enabled so it does not boot table to page 1
77
78
  // We can extend this for more usecases, but for now scoping it only for inlineRowLoading
@@ -235,22 +236,26 @@ export function useTableState({
235
236
  // Handle row pinning changes
236
237
  useEffect(() => {
237
238
  const topPins = pinnedRows?.value?.top ?? [];
238
- if (topPins.length === 0) {
239
- onRowPinningChange({ top: [] });
240
- return;
241
- }
239
+ const bottomPins = pinnedRows?.value?.bottom ?? [];
240
+
242
241
  const rows = table.getRowModel().rows;
243
242
  const collectAllDescendantIds = (subs: Row<GenericObject>[]): string[] =>
244
243
  subs.flatMap(r => [r.id, ...collectAllDescendantIds(r.subRows)]);
245
- const allPinned: string[] = [];
246
- topPins.forEach(id => {
247
- const parent = rows.find(r => r.id === id && r.depth === 0);
248
- if (parent) {
249
- allPinned.push(parent.id, ...collectAllDescendantIds(parent.subRows));
250
- }
244
+ const expandPins = (ids: string[]): string[] => {
245
+ const allPinned: string[] = [];
246
+ ids.forEach(id => {
247
+ const parent = rows.find(r => r.id === id && r.depth === 0);
248
+ if (parent) {
249
+ allPinned.push(parent.id, ...collectAllDescendantIds(parent.subRows));
250
+ }
251
+ });
252
+ return allPinned;
253
+ };
254
+ onRowPinningChange({
255
+ top: expandPins(topPins),
256
+ bottom: expandPins(bottomPins),
251
257
  });
252
- onRowPinningChange({ top: allPinned });
253
- }, [table, pinnedRows?.value?.top?.join(',')]);
258
+ }, [table, pinnedRows?.value?.top?.join(','), pinnedRows?.value?.bottom?.join(',')]);
254
259
 
255
260
  // Set pagination state when pagination is enabled
256
261
  useEffect(() => {
@@ -747,6 +747,9 @@
747
747
  // Row Pinning - React uses inline style; Rails passes same style via html_options from table_body
748
748
  .pinned-row {
749
749
  box-shadow: 0 4px 10px 0 rgba($shadow, 0.16) !important;
750
+ &.pinned-row-bottom {
751
+ box-shadow: 0 -3px 8px 0 rgba($shadow, 0.1) !important;
752
+ }
750
753
  }
751
754
 
752
755
  // For Rails, we can't target the &:last-child since collapsed rows are display: none;
@@ -696,7 +696,7 @@ test("customRenderer prop functions as expected", () => {
696
696
  expect(pill).toBeInTheDocument()
697
697
  })
698
698
 
699
- test("pinnedRows prop renders pinned rows at top", () => {
699
+ test("pinnedRows prop renders top pinned rows at top", () => {
700
700
  const pinnedRowsControl = {
701
701
  value: { top: ["1", "3"] },
702
702
  onChange: jest.fn()
@@ -721,6 +721,31 @@ test("pinnedRows prop renders pinned rows at top", () => {
721
721
  expect(firstPinnedRow).toHaveStyle("background-color: white")
722
722
  })
723
723
 
724
+ test("pinnedRows prop renders bottom pinned rows at bottom", () => {
725
+ const pinnedRowsControl = {
726
+ value: { bottom: ["1", "3"] },
727
+ onChange: jest.fn()
728
+ }
729
+
730
+ render(
731
+ <AdvancedTable
732
+ columnDefinitions={columnDefinitions}
733
+ data={{ testid: testId }}
734
+ pinnedRows={pinnedRowsControl}
735
+ tableData={MOCK_DATA_WITH_ID}
736
+ />
737
+ )
738
+
739
+ const kit = screen.getByTestId(testId)
740
+ const pinnedRows = kit.querySelectorAll(".pinned-row-bottom")
741
+
742
+ expect(pinnedRows).toHaveLength(2)
743
+
744
+ const lastPinnedRow = pinnedRows[0]
745
+ expect(lastPinnedRow).toHaveStyle("position: sticky")
746
+ expect(lastPinnedRow).toHaveStyle("background-color: white")
747
+ })
748
+
724
749
  test("columnStyling.headerAlignment aligns header as expected", () => {
725
750
  const styledColumnDefs = [
726
751
  {
@@ -1,6 +1,7 @@
1
1
  import React, { useState } from "react"
2
2
  import AdvancedTable from '../_advanced_table'
3
3
  import MOCK_DATA_WITH_ID from "./advanced_table_mock_data_with_id.json"
4
+ import Caption from "../../pb_caption/_caption"
4
5
 
5
6
  const AdvancedTableRowPinning = (props) => {
6
7
  const columnDefinitions = [
@@ -35,14 +36,30 @@ const AdvancedTableRowPinning = (props) => {
35
36
  },
36
37
  ]
37
38
 
38
- const [pinnedRows, setPinnedRows] = useState({top: ["8"]})
39
+ const [pinnedRowsTop, setPinnedRowsTop] = useState({top: ["8"]})
40
+ const [pinnedRowsBottom, setPinnedRowsBottom] = useState({bottom: ["8"]})
39
41
 
40
42
  return (
41
43
  <div>
44
+ <Caption text="Pinned Rows Top" />
42
45
  <AdvancedTable
43
46
  columnDefinitions={columnDefinitions}
44
47
  maxHeight="xs"
45
- pinnedRows={{value: pinnedRows, onChange: setPinnedRows}}
48
+ pinnedRows={{value: pinnedRowsTop, onChange: setPinnedRowsTop}}
49
+ tableData={MOCK_DATA_WITH_ID}
50
+ tableProps={{sticky: true}}
51
+ {...props}
52
+ >
53
+ <AdvancedTable.Header enableSorting />
54
+ <AdvancedTable.Body />
55
+ </AdvancedTable>
56
+ <Caption marginTop="md"
57
+ text="Pinned Rows Bottom"
58
+ />
59
+ <AdvancedTable
60
+ columnDefinitions={columnDefinitions}
61
+ maxHeight="xs"
62
+ pinnedRows={{value: pinnedRowsBottom, onChange: setPinnedRowsBottom}}
46
63
  tableData={MOCK_DATA_WITH_ID}
47
64
  tableProps={{sticky: true}}
48
65
  {...props}
@@ -1,7 +1,7 @@
1
- Use the `pinnedRows` prop to pin specific rows to the top of an Advanced Table. Pinned rows will remain at the top when scrolling through table data and will not change position if sorting is used.
1
+ Use the `pinnedRows` prop to pin specific rows to the top or bottom of an Advanced Table. Pinned rows will remain at the top or bottom when scrolling through table data and will not change position if sorting is used.
2
2
 
3
3
  **NOTE:**
4
4
  - Sticky header required: Pinned rows must be used with `sticky: true` via `tableProps` (works with both responsive and non-responsive tables)
5
5
  - Row ids required: Each object within the `tableData` Array must contain a unique id in order to attach an id to all Rows for this to function.
6
- - `pinnedRows` takes an array of row ids to the `top` property as shown in the code snippet below.
6
+ - `pinnedRows` takes an array of row ids to the `top` or `bottom` property as shown in the code snippet below (both can be used on the same table).
7
7
  - For expandable rows, use the parent id in `pinnedRows`, all its children will automatically be pinned with it. If id for a child is passed in without parent being pinned, nothing will be pinned.
@@ -89,5 +89,4 @@ examples:
89
89
  - advanced_table_column_styling_background_multi: Column Styling Background Color with Multiple Headers
90
90
  - advanced_table_padding_control: Padding Control using Column Styling
91
91
  - advanced_table_column_border_color: Column Group Border Color
92
- - advanced_table_fullscreen: Fullscreen
93
92
  - advanced_table_infinite_scroll: Infinite Scroll
@@ -106,7 +106,7 @@
106
106
  "platforms": [
107
107
  "rails"
108
108
  ],
109
- "type": "string"
109
+ "type": "GenericObject"
110
110
  },
111
111
  "required": {
112
112
  "platforms": [
@@ -106,7 +106,7 @@
106
106
  "platforms": [
107
107
  "rails"
108
108
  ],
109
- "type": "string"
109
+ "type": "GenericObject"
110
110
  }
111
111
  },
112
112
  "globalProps": true,
@@ -80,3 +80,9 @@
80
80
  content: none;
81
81
  }
82
82
  }
83
+
84
+ .pb_date_picker_floating_shell {
85
+ margin: 0;
86
+ padding: 0;
87
+ pointer-events: auto;
88
+ }
@@ -1,4 +1,4 @@
1
- import React, { useEffect } from 'react'
1
+ import React, { useContext, useEffect } from 'react'
2
2
  import classnames from 'classnames'
3
3
 
4
4
  import { buildAriaProps, buildCss, buildDataProps, buildHtmlProps } from '../utilities/props'
@@ -6,6 +6,7 @@ import { deprecatedProps, globalProps, GlobalProps } from '../utilities/globalPr
6
6
  import { getAllIcons } from "../utilities/icons/allicons"
7
7
  import { camelToSnakeCase } from '../utilities/text'
8
8
 
9
+ import { DialogContext } from '../pb_dialog/_dialog_context'
9
10
  import datePickerHelper from './date_picker_helper'
10
11
  import Icon from '../pb_icon/_icon'
11
12
  import Caption from '../pb_caption/_caption'
@@ -149,6 +150,8 @@ const DatePicker = (props: DatePickerProps): React.ReactElement => {
149
150
  syncEndWith,
150
151
  } = props
151
152
 
153
+ const dialogCtx = useContext(DialogContext)
154
+
152
155
  const ariaProps = buildAriaProps(aria)
153
156
  const normalizedDefaultDate = normalizeDefaultDate(defaultDate)
154
157
  const filterResetDefaultSerialized = serializeDefaultDateForFilterReset(normalizedDefaultDate)
@@ -186,6 +189,7 @@ const DatePicker = (props: DatePickerProps): React.ReactElement => {
186
189
  format,
187
190
  hideIcon,
188
191
  inLine,
192
+ inline: inLine,
189
193
  maxDate,
190
194
  minDate,
191
195
  mode,
@@ -208,8 +212,18 @@ const DatePicker = (props: DatePickerProps): React.ReactElement => {
208
212
  syncStartWith,
209
213
  syncEndWith,
210
214
  required: false,
215
+ dialogPortalTarget: dialogCtx?.selectMenuPortalTarget ?? null,
211
216
  }, scrollContainer)
212
- }, initializeOnce ? [] : undefined)
217
+
218
+ return () => {
219
+ const input = document.getElementById(String(pickerId)) as
220
+ | (HTMLElement & { _flatpickr?: { destroy: () => void }; _pbDatePickerOpenUnsub?: () => void })
221
+ | null
222
+ input?._pbDatePickerOpenUnsub?.()
223
+ delete input?._pbDatePickerOpenUnsub
224
+ input?._flatpickr?.destroy()
225
+ }
226
+ }, initializeOnce ? [initializeOnce, dialogCtx?.selectMenuPortalTarget, pickerId] : undefined)
213
227
 
214
228
  const filteredProps = {...props}
215
229
  if (filteredProps.marginBottom === undefined) {
@@ -96,22 +96,73 @@
96
96
  })
97
97
  }
98
98
 
99
+ const disconnectPopoverWatch = (input) => {
100
+ if (!input) return
101
+
102
+ if (input._pbDatePickerPopoverObserver) {
103
+ input._pbDatePickerPopoverObserver.disconnect()
104
+ delete input._pbDatePickerPopoverObserver
105
+ }
106
+
107
+ delete input.dataset.pbDatePickerPopoverWatch
108
+ }
109
+
99
110
  const loadDatePicker = () => {
100
111
  const input = document.getElementById("<%= object.picker_id %>")
101
112
 
102
- if (!input || input._flatpickr) return true
113
+ if (!input || input._flatpickr) {
114
+ disconnectPopoverWatch(input)
115
+ return true
116
+ }
103
117
  if (typeof window.datePickerHelper !== "function") return false
104
118
 
119
+ const popoverTooltip = input.closest(".pb_popover_tooltip")
120
+ if (popoverTooltip && !popoverTooltip.classList.contains("show")) {
121
+ return false
122
+ }
123
+
105
124
  window.datePickerHelper(<%= object.date_picker_config %>, "<%= object.scroll_container %>")
106
125
  initQuickPickChangeListener(input)
126
+ disconnectPopoverWatch(input)
107
127
 
108
128
  return true
109
129
  }
110
130
 
131
+ const watchPopoverVisibility = () => {
132
+ const input = document.getElementById("<%= object.picker_id %>")
133
+ if (!input || input.dataset.pbDatePickerPopoverWatch) return
134
+
135
+ const popoverTooltip = input.closest(".pb_popover_tooltip")
136
+ if (!popoverTooltip) return
137
+
138
+ input.dataset.pbDatePickerPopoverWatch = "true"
139
+ const tryInitWhenVisible = () => {
140
+ if (!input.isConnected || !popoverTooltip.isConnected) {
141
+ disconnectPopoverWatch(input)
142
+ return
143
+ }
144
+
145
+ if (popoverTooltip.classList.contains("show")) {
146
+ loadDatePicker()
147
+ }
148
+ }
149
+
150
+ const observer = new MutationObserver(tryInitWhenVisible)
151
+ input._pbDatePickerPopoverObserver = observer
152
+ observer.observe(popoverTooltip, { attributes: true, attributeFilter: ["class"] })
153
+ tryInitWhenVisible()
154
+ }
155
+
111
156
  let attempts = 0
112
157
  const retryLoad = () => {
113
158
  if (loadDatePicker()) return
114
159
 
160
+ const input = document.getElementById("<%= object.picker_id %>")
161
+ if (input?.closest(".pb_popover_tooltip")) {
162
+ watchPopoverVisibility()
163
+ return
164
+ }
165
+
115
166
  if (attempts++ < 20) {
116
167
  setTimeout(retryLoad, 100)
117
168
  }
@@ -134,6 +185,12 @@
134
185
  if (<%= !object.custom_event_type.empty? %>) {
135
186
  window.addEventListener("<%= object.custom_event_type %>", retryLoad)
136
187
  }
188
+
189
+ document.addEventListener("turbo:before-cache", () => {
190
+ const input = document.getElementById("<%= object.picker_id %>")
191
+ disconnectPopoverWatch(input)
192
+ input?._flatpickr?.destroy()
193
+ })
137
194
  })()
138
195
  <% end %>
139
196
  <% end %>