playbook_ui 14.11.1 → 14.12.0.pre.alpha.PBNTR720railscarddraggable5649

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 (159) 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/CustomCell.tsx +18 -2
  4. data/app/pb_kits/playbook/pb_advanced_table/Components/TableHeaderCell.tsx +27 -5
  5. data/app/pb_kits/playbook/pb_advanced_table/SubKits/TableBody.tsx +17 -2
  6. data/app/pb_kits/playbook/pb_advanced_table/SubKits/TableHeader.tsx +23 -1
  7. data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.scss +29 -0
  8. data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.tsx +61 -4
  9. data/app/pb_kits/playbook/pb_advanced_table/advanced_table.html.erb +1 -1
  10. data/app/pb_kits/playbook/pb_advanced_table/advanced_table.rb +2 -0
  11. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_no_subrows.jsx +50 -0
  12. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_pagination.jsx +1 -0
  13. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_pagination_with_props.jsx +1 -0
  14. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_selectable_rows.jsx +60 -0
  15. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_selectable_rows.md +5 -0
  16. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_selectable_rows_actions.jsx +78 -0
  17. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_selectable_rows_actions.md +1 -0
  18. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_selectable_rows_header.jsx +53 -0
  19. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_selectable_rows_header.md +1 -0
  20. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_selectable_rows_no_subrows.jsx +52 -0
  21. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_selectable_rows_no_subrows.md +1 -0
  22. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_sort_control.md +2 -2
  23. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_table_props.html.erb +33 -0
  24. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_table_props_rails.md +1 -0
  25. data/app/pb_kits/playbook/pb_advanced_table/docs/advanced_table_mock_data_no_subrows.json +42 -0
  26. data/app/pb_kits/playbook/pb_advanced_table/docs/advanced_table_mock_data_with_id.json +299 -0
  27. data/app/pb_kits/playbook/pb_advanced_table/docs/example.yml +6 -0
  28. data/app/pb_kits/playbook/pb_advanced_table/docs/index.js +6 -1
  29. data/app/pb_kits/playbook/pb_button/button.html.erb +2 -3
  30. data/app/pb_kits/playbook/pb_card/card.html.erb +21 -2
  31. data/app/pb_kits/playbook/pb_card/card.rb +7 -0
  32. data/app/pb_kits/playbook/pb_checkbox/checkbox.html.erb +1 -6
  33. data/app/pb_kits/playbook/pb_collapsible/collapsible.html.erb +3 -1
  34. data/app/pb_kits/playbook/pb_collapsible/collapsible.rb +3 -0
  35. data/app/pb_kits/playbook/pb_date_picker/date_picker.html.erb +24 -16
  36. data/app/pb_kits/playbook/pb_date_picker/date_picker.rb +2 -0
  37. data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_default_date.md +1 -1
  38. data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_turbo_frames.html.erb +13 -0
  39. data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_turbo_frames_rails.md +3 -0
  40. data/app/pb_kits/playbook/pb_date_picker/docs/example.yml +1 -0
  41. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_cards_rails.html.erb +1 -3
  42. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_cards_rails.md +7 -0
  43. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_list_rails.html.erb +3 -9
  44. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_list_rails.md +5 -0
  45. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_selectable_list_rails.html.erb +38 -0
  46. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_selectable_list_rails.md +3 -0
  47. data/app/pb_kits/playbook/pb_draggable/docs/example.yml +1 -0
  48. data/app/pb_kits/playbook/pb_drawer/_drawer.scss +145 -183
  49. data/app/pb_kits/playbook/pb_drawer/_drawer.tsx +158 -268
  50. data/app/pb_kits/playbook/pb_drawer/context.ts +11 -0
  51. data/app/pb_kits/playbook/pb_drawer/docs/_drawer_behavior.jsx +38 -0
  52. data/app/pb_kits/playbook/pb_drawer/docs/_drawer_borders.jsx +3 -45
  53. data/app/pb_kits/playbook/pb_drawer/docs/_drawer_breakpoints.jsx +0 -1
  54. data/app/pb_kits/playbook/pb_drawer/docs/_drawer_default.jsx +9 -16
  55. data/app/pb_kits/playbook/pb_drawer/docs/_drawer_menu.jsx +44 -19
  56. data/app/pb_kits/playbook/pb_drawer/docs/_drawer_menu.md +21 -3
  57. data/app/pb_kits/playbook/pb_drawer/docs/_drawer_overlay.jsx +16 -21
  58. data/app/pb_kits/playbook/pb_drawer/docs/_drawer_sizes.jsx +2 -19
  59. data/app/pb_kits/playbook/pb_drawer/docs/example.yml +2 -1
  60. data/app/pb_kits/playbook/pb_drawer/docs/index.js +1 -0
  61. data/app/pb_kits/playbook/pb_drawer/drawer.test.jsx +5 -5
  62. data/app/pb_kits/playbook/pb_drawer/hooks/useBreakpoint.tsx +60 -0
  63. data/app/pb_kits/playbook/pb_drawer/hooks/useDrawerAnimation.tsx +21 -0
  64. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_subtle_variant.md +1 -1
  65. data/app/pb_kits/playbook/pb_dropdown/dropdown.html.erb +7 -12
  66. data/app/pb_kits/playbook/pb_dropdown/dropdown_container.html.erb +9 -14
  67. data/app/pb_kits/playbook/pb_dropdown/dropdown_option.html.erb +6 -11
  68. data/app/pb_kits/playbook/pb_dropdown/dropdown_trigger.html.erb +8 -14
  69. data/app/pb_kits/playbook/pb_icon_button/_icon_button.scss +78 -0
  70. data/app/pb_kits/playbook/pb_icon_button/docs/_icon_button_default.html.erb +3 -0
  71. data/app/pb_kits/playbook/pb_icon_button/docs/example.yml +7 -0
  72. data/app/pb_kits/playbook/pb_icon_button/icon_button.html.erb +16 -0
  73. data/app/pb_kits/playbook/pb_icon_button/icon_button.rb +22 -0
  74. data/app/pb_kits/playbook/pb_list/item.html.erb +30 -8
  75. data/app/pb_kits/playbook/pb_list/item.rb +7 -0
  76. data/app/pb_kits/playbook/pb_list/list.html.erb +31 -11
  77. data/app/pb_kits/playbook/pb_list/list.rb +4 -0
  78. data/app/pb_kits/playbook/pb_loading_inline/_loading_inline.tsx +6 -1
  79. data/app/pb_kits/playbook/pb_multiple_users/_multiple_users.scss +4 -0
  80. data/app/pb_kits/playbook/pb_multiple_users/_multiple_users.tsx +1 -0
  81. data/app/pb_kits/playbook/pb_multiple_users/multiple_users.html.erb +1 -1
  82. data/app/pb_kits/playbook/pb_phone_number_input/_phone_number_input.tsx +30 -12
  83. data/app/pb_kits/playbook/pb_phone_number_input/docs/_phone_number_input_format.html.erb +15 -0
  84. data/app/pb_kits/playbook/pb_phone_number_input/docs/_phone_number_input_format.jsx +24 -0
  85. data/app/pb_kits/playbook/pb_phone_number_input/docs/_phone_number_input_format.md +1 -0
  86. data/app/pb_kits/playbook/pb_phone_number_input/docs/example.yml +3 -1
  87. data/app/pb_kits/playbook/pb_phone_number_input/docs/index.js +1 -0
  88. data/app/pb_kits/playbook/pb_phone_number_input/phone_number_input.rb +3 -0
  89. data/app/pb_kits/playbook/pb_phone_number_input/phone_number_input.test.js +20 -1
  90. data/app/pb_kits/playbook/pb_radio/_radio.scss +12 -8
  91. data/app/pb_kits/playbook/pb_radio/docs/_radio_custom_children.jsx +8 -3
  92. data/app/pb_kits/playbook/pb_select/_select.scss +3 -5
  93. data/app/pb_kits/playbook/pb_select/_select.tsx +5 -1
  94. data/app/pb_kits/playbook/pb_select/select.html.erb +2 -2
  95. data/app/pb_kits/playbook/pb_selectable_icon/_selectable_icon.tsx +9 -1
  96. data/app/pb_kits/playbook/pb_selectable_icon/docs/_selectable_icon_default.jsx +4 -1
  97. data/app/pb_kits/playbook/pb_selectable_icon/docs/_selectable_icon_single_select.jsx +4 -1
  98. data/app/pb_kits/playbook/pb_selectable_list/selectable_list.html.erb +17 -3
  99. data/app/pb_kits/playbook/pb_selectable_list/selectable_list.rb +3 -0
  100. data/app/pb_kits/playbook/pb_selectable_list/selectable_list_item.html.erb +11 -4
  101. data/app/pb_kits/playbook/pb_selectable_list/selectable_list_item.rb +3 -0
  102. data/app/pb_kits/playbook/pb_table/_table.tsx +2 -3
  103. data/app/pb_kits/playbook/pb_table/docs/_table_sticky_columns.html.erb +74 -0
  104. data/app/pb_kits/playbook/pb_table/docs/_table_sticky_columns_rails.md +3 -0
  105. data/app/pb_kits/playbook/pb_table/docs/_table_sticky_left_columns_rails.md +2 -2
  106. data/app/pb_kits/playbook/pb_table/docs/_table_sticky_right_columns.html.erb +74 -0
  107. data/app/pb_kits/playbook/pb_table/docs/_table_sticky_right_columns_rails.md +3 -0
  108. data/app/pb_kits/playbook/pb_table/docs/_table_with_collapsible.html.erb +47 -0
  109. data/app/pb_kits/playbook/pb_table/docs/_table_with_collapsible_rails.md +2 -0
  110. data/app/pb_kits/playbook/pb_table/docs/example.yml +3 -0
  111. data/app/pb_kits/playbook/pb_table/index.ts +187 -88
  112. data/app/pb_kits/playbook/pb_table/styles/_collapsible.scss +12 -0
  113. data/app/pb_kits/playbook/pb_table/styles/_scroll.scss +6 -5
  114. data/app/pb_kits/playbook/pb_table/table.html.erb +1 -1
  115. data/app/pb_kits/playbook/pb_table/table.rb +17 -2
  116. data/app/pb_kits/playbook/pb_table/table_row.html.erb +20 -1
  117. data/app/pb_kits/playbook/pb_table/table_row.rb +5 -0
  118. data/app/pb_kits/playbook/pb_table/utilities/addDataTitle.ts +22 -0
  119. data/app/pb_kits/playbook/pb_text_input/docs/_text_input_mask.html.erb +46 -0
  120. data/app/pb_kits/playbook/pb_text_input/docs/_text_input_mask_rails.md +3 -0
  121. data/app/pb_kits/playbook/pb_text_input/docs/example.yml +2 -1
  122. data/app/pb_kits/playbook/pb_text_input/index.js +103 -0
  123. data/app/pb_kits/playbook/pb_text_input/text_input.html.erb +4 -0
  124. data/app/pb_kits/playbook/pb_text_input/text_input.rb +33 -3
  125. data/app/pb_kits/playbook/pb_timeline/_timeline.scss +30 -30
  126. data/app/pb_kits/playbook/pb_typeahead/_typeahead.tsx +3 -2
  127. data/app/pb_kits/playbook/pb_typeahead/components/ClearIndicator.tsx +12 -4
  128. data/app/pb_kits/playbook/pb_typeahead/components/Control.tsx +5 -1
  129. data/app/pb_kits/playbook/pb_typeahead/components/IndicatorsContainer.tsx +8 -3
  130. data/app/pb_kits/playbook/pb_typeahead/components/MenuList.tsx +6 -1
  131. data/app/pb_kits/playbook/pb_typeahead/components/Option.tsx +21 -6
  132. data/app/pb_kits/playbook/pb_typeahead/components/Placeholder.tsx +13 -6
  133. data/app/pb_kits/playbook/pb_typeahead/components/ValueContainer.tsx +7 -3
  134. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_custom_menu_list.jsx +2 -0
  135. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_truncated_text.html.erb +19 -0
  136. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_truncated_text.jsx +27 -0
  137. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_truncated_text.md +1 -0
  138. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_with_pills_async.jsx +4 -2
  139. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_with_pills_async_custom_options.jsx +5 -5
  140. data/app/pb_kits/playbook/pb_typeahead/docs/example.yml +2 -0
  141. data/app/pb_kits/playbook/pb_typeahead/docs/index.js +1 -0
  142. data/dist/chunks/_typeahead-BWwaAo_0.js +36 -0
  143. data/dist/chunks/_weekday_stacked-zyBCd1s8.js +45 -0
  144. data/dist/chunks/lazysizes-B7xYodB-.js +1 -0
  145. data/dist/chunks/{lib-B7sgJtGS.js → lib-kMuhBuU7.js} +2 -2
  146. data/dist/chunks/{pb_form_validation-C5Cc0-1v.js → pb_form_validation-DBJ0wZuS.js} +1 -1
  147. data/dist/chunks/vendor.js +1 -1
  148. data/dist/menu.yml +6 -0
  149. data/dist/playbook-doc.js +1 -1
  150. data/dist/playbook-rails-react-bindings.js +1 -1
  151. data/dist/playbook-rails.js +1 -1
  152. data/dist/playbook.css +1 -1
  153. data/lib/playbook/version.rb +2 -2
  154. metadata +66 -9
  155. data/dist/chunks/_typeahead-C2iCBqxQ.js +0 -36
  156. data/dist/chunks/_weekday_stacked-E-5KcEkc.js +0 -45
  157. data/dist/chunks/lazysizes-DHz07jlL.js +0 -1
  158. /data/app/pb_kits/playbook/pb_advanced_table/docs/{_advanced_table_table_props.md → _advanced_table_table_props_react.md} +0 -0
  159. /data/app/pb_kits/playbook/pb_table/docs/{_table_with_collapsible.md → _table_with_collapsible_react.md} +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 684dfcc3e0b2d271c0ef3992c66895d5bf59f7814908e97b4ba0a6a2fd3a35c6
4
- data.tar.gz: 8cff029a4d16a46c0d11292767c7faed0fed272b1102316c5c6988289b145f9b
3
+ metadata.gz: bfb340a31e2bb74d3749938720b1a44b2217e841d785f287f45499b70d8f03e5
4
+ data.tar.gz: 3cc515a9004e7a4558bd62bbda022c354e2fdfd15a9bd2541324a9d50287ae5c
5
5
  SHA512:
6
- metadata.gz: cf605e9ea95eca375c9efc8a112416d373958b9c5b0cd2bb4ea63495a6e6a97e22776d372d96894d2060c0c2c02ee671943390b06dbf0b35dded14de3b531a09
7
- data.tar.gz: 8c2b6329d1a8ed96313eb9cacae23f86c2801ebdf4fe24de3070b969b79758753ca5f7e2507956482e4560fac781f6dc443f55cf0844ea749f2e7dcd26b1c92e
6
+ metadata.gz: 93eab8412f7e086ffd7fa534aff415b0f648ec73e247a281cd1e2dc357144dc90bf2d63dc7c36c027769b2ee6e7d1355852cf5f36b159a3559f2a491315dc174
7
+ data.tar.gz: 4a15e5855591a6a817a683f701958ccae8b6b10d1a9d825c9ebcff15c4e3b276b5eb08c12f7858f82ea6d8604fbdd0aee419dddffe02012b0992891767f46a16
@@ -1,3 +1,4 @@
1
+
1
2
  @import 'pb_advanced_table/advanced_table';
2
3
  @import 'pb_avatar/avatar';
3
4
  @import 'pb_avatar_action_button/avatar_action_button';
@@ -108,6 +109,7 @@
108
109
  @import 'pb_user_badge/user_badge';
109
110
  @import 'pb_walkthrough/walkthrough';
110
111
  @import 'pb_weekday_stacked/weekday_stacked';
112
+ @import 'pb_icon_button/icon_button';
111
113
  @import 'utilities/mixins';
112
114
  @import 'utilities/spacing';
113
115
  @import 'utilities/cursor';
@@ -8,6 +8,7 @@ import { GlobalProps } from "../../utilities/globalProps"
8
8
  import Flex from "../../pb_flex/_flex"
9
9
  import FlexItem from "../../pb_flex/_flex_item"
10
10
  import Icon from "../../pb_icon/_icon"
11
+ import Checkbox from "../../pb_checkbox/_checkbox"
11
12
 
12
13
  import AdvancedTableContext from "../Context/AdvancedTableContext"
13
14
 
@@ -17,6 +18,7 @@ interface CustomCellProps {
17
18
  row: Row<GenericObject>
18
19
  value?: string
19
20
  customRenderer?: (row: Row<GenericObject>, value: string | undefined) => React.ReactNode
21
+ selectableRows?: boolean
20
22
  }
21
23
 
22
24
  export const CustomCell = ({
@@ -25,8 +27,9 @@ export const CustomCell = ({
25
27
  row,
26
28
  value,
27
29
  customRenderer,
30
+ selectableRows,
28
31
  }: CustomCellProps & GlobalProps) => {
29
- const { setExpanded, expanded, expandedControl, inlineRowLoading } = useContext(AdvancedTableContext);
32
+ const { setExpanded, expanded, expandedControl, inlineRowLoading, hasAnySubRows } = useContext(AdvancedTableContext);
30
33
 
31
34
  const handleOnExpand = (row: Row<GenericObject>) => {
32
35
  onRowToggleClick && onRowToggleClick(row);
@@ -41,10 +44,23 @@ export const CustomCell = ({
41
44
 
42
45
  return (
43
46
  <div style={{ paddingLeft: `${row.depth * 1.25}em` }}>
44
- <Flex alignItems="center"
47
+ <Flex
48
+ alignItems="center"
45
49
  columnGap="xs"
50
+ justify={!hasAnySubRows ? "end" : "start"}
46
51
  orientation="row"
47
52
  >
53
+ {
54
+ selectableRows && hasAnySubRows && (
55
+ <Checkbox
56
+ checked={row.getIsSelected()}
57
+ disabled={!row.getCanSelect()}
58
+ indeterminate={row.getIsSomeSelected()}
59
+ name={row.id}
60
+ onChange={row.getToggleSelectedHandler()}
61
+ />
62
+ )
63
+ }
48
64
  {renderButton ? (
49
65
  <button
50
66
  className="gray-icon expand-toggle-icon"
@@ -1,12 +1,13 @@
1
1
  import React, { useContext } from "react"
2
2
  import classnames from "classnames"
3
- import { flexRender, Header } from "@tanstack/react-table"
3
+ import { flexRender, Header, Table } from "@tanstack/react-table"
4
4
 
5
5
  import { GenericObject } from "../../types"
6
6
 
7
7
  import { GlobalProps } from "../../utilities/globalProps"
8
8
 
9
9
  import Flex from "../../pb_flex/_flex"
10
+ import Checkbox from "../../pb_checkbox/_checkbox"
10
11
 
11
12
  import { SortIconButton } from "./SortIconButton"
12
13
  import { ToggleIconButton } from "./ToggleIconButton"
@@ -24,6 +25,7 @@ type TableHeaderCellProps = {
24
25
  isPinnedLeft?: boolean
25
26
  loading?: boolean
26
27
  sortIcon?: string | string[]
28
+ table?: Table<GenericObject>
27
29
  } & GlobalProps
28
30
 
29
31
  export const TableHeaderCell = ({
@@ -35,9 +37,13 @@ export const TableHeaderCell = ({
35
37
  isPinnedLeft = false,
36
38
  loading,
37
39
  sortIcon,
40
+ table
38
41
  }: TableHeaderCellProps) => {
39
- const { sortControl, responsive } = useContext(AdvancedTableContext)
42
+ const { sortControl, responsive, selectableRows, hasAnySubRows, showActionsBar } =
43
+ useContext(AdvancedTableContext);
40
44
 
45
+ type justifyTypes = "none" | "center" | "start" | "end" | "between" | "around" | "evenly"
46
+
41
47
  const toggleSortButton = (event: React.SyntheticEvent) => {
42
48
  if (sortControl) {
43
49
  const sortIsDesc = header?.column.getIsSorted() === "desc"
@@ -59,6 +65,7 @@ export const TableHeaderCell = ({
59
65
 
60
66
  const cellClassName = classnames(
61
67
  "table-header-cells",
68
+ `${showActionsBar && "header-cells-with-actions"}`,
62
69
  `${isChrome() ? "chrome-styles" : ""}`,
63
70
  `${enableSorting ? "table-header-cells-active" : ""}`,
64
71
  { "pinned-left": responsive === "scroll" && isPinnedLeft },
@@ -82,8 +89,14 @@ const isToggleExpansionEnabled =
82
89
  (enableToggleExpansion === "all" || "header") &&
83
90
  enableToggleExpansion !== "none"
84
91
 
85
- const justifyHeader = isLeafColumn ? "end" : "center"
92
+ let justifyHeader:justifyTypes;
86
93
 
94
+ if (header?.index === 0 && hasAnySubRows) {
95
+ justifyHeader = enableSorting ? "between" : "start";
96
+ } else {
97
+ justifyHeader = isLeafColumn ? "end" : "center";
98
+ }
99
+
87
100
  return (
88
101
  <th
89
102
  align="right"
@@ -102,9 +115,18 @@ const justifyHeader = isLeafColumn ? "end" : "center"
102
115
  ) : (
103
116
  <Flex
104
117
  alignItems="center"
105
- justify={header?.index === 0 && enableSorting ? "between" : header?.index === 0 && !enableSorting ? "start" : justifyHeader}
118
+ justify={justifyHeader}
106
119
  >
107
- {isToggleExpansionEnabled && (
120
+ {
121
+ selectableRows && header?.index === 0 && hasAnySubRows && (
122
+ <Checkbox
123
+ checked={table?.getIsAllRowsSelected()}
124
+ indeterminate={table?.getIsSomeRowsSelected()}
125
+ onChange={table?.getToggleAllRowsSelectedHandler()}
126
+ />
127
+ )
128
+ }
129
+ {isToggleExpansionEnabled && hasAnySubRows && (
108
130
  <ToggleIconButton onClick={handleExpandOrCollapse} />
109
131
  )}
110
132
 
@@ -9,6 +9,7 @@ import { globalProps } from "../../utilities/globalProps"
9
9
  import { isChrome } from "../Utilities/BrowserCheck"
10
10
 
11
11
  import LoadingInline from "../../pb_loading_inline/_loading_inline"
12
+ import Checkbox from "../../pb_checkbox/_checkbox"
12
13
 
13
14
  import { SubRowHeaderRow } from "../Components/SubRowHeaderRow"
14
15
  import { LoadingCell } from "../Components/LoadingCell"
@@ -42,6 +43,8 @@ export const TableBody = ({
42
43
  loading,
43
44
  responsive,
44
45
  table,
46
+ selectableRows,
47
+ hasAnySubRows
45
48
  } = useContext(AdvancedTableContext)
46
49
 
47
50
  const classes = classnames(
@@ -65,7 +68,7 @@ export const TableBody = ({
65
68
  const numberOfColumns = table.getAllFlatColumns().length
66
69
  const isDataLoading = isExpandable && (inlineRowLoading && rowHasNoChildren) && (row.depth < columnDefinitions[0].cellAccessors?.length)
67
70
  const rowBackground = isExpandable && ((!inlineRowLoading && row.getCanExpand()) || (inlineRowLoading && rowHasNoChildren))
68
-
71
+ const rowColor = row.getIsSelected() ? "bg-row-selection" : rowBackground ? "bg-silver" : "bg-white"
69
72
  return (
70
73
  <React.Fragment key={`${row.index}-${row.id}-${row.depth}-row`}>
71
74
  {isFirstChildofSubrow && subRowHeaders && (
@@ -79,11 +82,23 @@ export const TableBody = ({
79
82
  />
80
83
  )}
81
84
  <tr
82
- className={`${rowBackground ? "bg-silver" : "bg-white"} ${
85
+ className={`${rowColor} ${
83
86
  row.depth > 0 ? `depth-sub-row-${row.depth}` : ""
84
87
  }`}
85
88
  id={`${row.index}-${row.id}-${row.depth}-row`}
86
89
  >
90
+ {/* Render custom checkbox column when we want selectableRows for non-expanding tables */}
91
+ {selectableRows && !hasAnySubRows && (
92
+ <td className="checkbox-cell">
93
+ <Checkbox
94
+ checked={row.getIsSelected()}
95
+ disabled={!row.getCanSelect()}
96
+ indeterminate={row.getIsSomeSelected()}
97
+ name={row.id}
98
+ onChange={row.getToggleSelectedHandler()}
99
+ />
100
+ </td>
101
+ )}
87
102
  {row.getVisibleCells().map((cell, i) => {
88
103
  const isPinnedLeft = columnPinning.left.includes(cell.column.id)
89
104
  const isLastCell = cell.column.parent?.columns.at(-1)?.id === cell.column.id
@@ -7,8 +7,10 @@ import { GenericObject } from "../../types"
7
7
  import { buildCss } from "../../utilities/props"
8
8
  import { globalProps } from "../../utilities/globalProps"
9
9
 
10
- import { TableHeaderCell } from "../Components/TableHeaderCell"
10
+ import Checkbox from "../../pb_checkbox/_checkbox"
11
11
 
12
+ import { TableHeaderCell } from "../Components/TableHeaderCell"
13
+ import { isChrome } from "../Utilities/BrowserCheck"
12
14
  import AdvancedTableContext from "../Context/AdvancedTableContext"
13
15
 
14
16
  type TableHeaderProps = {
@@ -34,6 +36,10 @@ export const TableHeader = ({
34
36
  handleExpandOrCollapse,
35
37
  loading,
36
38
  table,
39
+ hasAnySubRows,
40
+ showActionsBar,
41
+ selectableRows,
42
+ responsive
37
43
  } = useContext(AdvancedTableContext)
38
44
 
39
45
  const classes = classnames(
@@ -44,6 +50,12 @@ export const TableHeader = ({
44
50
 
45
51
  const columnPinning = table.getState().columnPinning;
46
52
 
53
+ const customCellClassnames = classnames(
54
+ "table-header-cells-custom",
55
+ `${showActionsBar && "header-cells-with-actions"}`,
56
+ `${isChrome() ? "chrome-styles" : ""}`,
57
+ `${responsive === "scroll" && "pinned-left"}`,
58
+ );
47
59
  return (
48
60
  <>
49
61
  <thead className={classes}
@@ -52,6 +64,15 @@ export const TableHeader = ({
52
64
  {/* Get the header groups (only one in this example) */}
53
65
  {table.getHeaderGroups().map((headerGroup: HeaderGroup<GenericObject>) => (
54
66
  <tr key={`${headerGroup.id}-headerGroup`}>
67
+ {!hasAnySubRows && selectableRows && (
68
+ <th className={customCellClassnames}>
69
+ <Checkbox
70
+ checked={table?.getIsAllRowsSelected()}
71
+ indeterminate={table?.getIsSomeRowsSelected()}
72
+ onChange={table?.getToggleAllRowsSelectedHandler()}
73
+ />
74
+ </th>
75
+ )}
55
76
  {headerGroup.headers.map(header => {
56
77
  const isPinnedLeft = columnPinning.left.includes(header.id)
57
78
  return (
@@ -65,6 +86,7 @@ export const TableHeader = ({
65
86
  key={`${header.id}-header`}
66
87
  loading={loading}
67
88
  sortIcon={sortIcon}
89
+ table={table}
68
90
  />
69
91
  )
70
92
  })}
@@ -23,10 +23,20 @@
23
23
  background-color: $white;
24
24
  }
25
25
 
26
+ .bg-row-selection {
27
+ background-color: $info_subtle;
28
+ }
29
+
26
30
  .full-width {
27
31
  width: 100%;
28
32
  }
29
33
 
34
+ .row-selection-actions-card {
35
+ border-bottom-right-radius: 0px !important;
36
+ border-bottom-left-radius: 0px !important;
37
+ border-bottom-color: transparent;
38
+ }
39
+
30
40
  .table-header-cells:first-child {
31
41
  min-width: 180px;
32
42
  }
@@ -47,6 +57,16 @@
47
57
  th[colspan]:not([colspan="1"]) {
48
58
  border-right: 1px solid $border_light !important;
49
59
  }
60
+ .table-header-cells-custom {
61
+ text-align:center;
62
+ [class^=pb_checkbox_kit] .pb_checkbox_label {
63
+ padding-left: 0px;
64
+ }
65
+ }
66
+ .header-cells-with-actions {
67
+ border-top-left-radius: 0px !important;
68
+ border-top-right-radius: 0px !important;
69
+ }
50
70
  }
51
71
 
52
72
  .pb_advanced_table_body {
@@ -59,6 +79,14 @@
59
79
  tr .pb_table_td:last-child {
60
80
  padding-right: 8px !important;
61
81
  }
82
+
83
+ .checkbox-cell {
84
+ display: flex;
85
+ justify-content: center;
86
+ [class^=pb_checkbox_kit] .pb_checkbox_label {
87
+ padding-left: 0px;
88
+ }
89
+ }
62
90
  }
63
91
 
64
92
 
@@ -116,6 +144,7 @@
116
144
 
117
145
  // Vertical separator
118
146
  .table-header-cells:first-child,
147
+ .table-header-cells-custom:first-child,
119
148
  td:first-child,
120
149
  .pb_table_td:first-child {
121
150
  box-shadow: 1px 0px 0px 0px $border_light !important;
@@ -12,12 +12,17 @@ import {
12
12
  Row,
13
13
  useReactTable,
14
14
  Getter,
15
+ RowSelectionState
15
16
  } from "@tanstack/react-table"
16
17
 
17
18
  import { buildAriaProps, buildCss, buildDataProps, buildHtmlProps } from "../utilities/props"
18
19
  import { globalProps, GlobalProps } from "../utilities/globalProps"
19
20
 
20
21
  import Table from "../pb_table/_table"
22
+ import Card from "../pb_card/_card"
23
+ import Caption from "../pb_caption/_caption"
24
+ import Flex from "../pb_flex/_flex"
25
+ import FlexItem from "../pb_flex/_flex_item"
21
26
 
22
27
  import AdvancedTableContext from "./Context/AdvancedTableContext"
23
28
 
@@ -30,6 +35,7 @@ import Pagination from "../pb_pagination/_pagination"
30
35
 
31
36
  type AdvancedTableProps = {
32
37
  aria?: { [key: string]: string }
38
+ actions?: React.ReactNode[] | React.ReactNode
33
39
  children?: React.ReactNode | React.ReactNode[]
34
40
  className?: string
35
41
  columnDefinitions: GenericObject[]
@@ -47,16 +53,20 @@ type AdvancedTableProps = {
47
53
  pagination?: boolean,
48
54
  paginationProps?: GenericObject
49
55
  responsive?: "scroll" | "none",
56
+ selectableRows?: boolean,
57
+ showActionsBar?: boolean,
50
58
  sortControl?: GenericObject
51
59
  tableData: GenericObject[]
52
60
  tableOptions?: GenericObject
53
61
  tableProps?: GenericObject
54
62
  toggleExpansionIcon?: string | string[]
63
+ onRowSelectionChange?: (arg: RowSelectionState) => void
55
64
  } & GlobalProps
56
65
 
57
66
  const AdvancedTable = (props: AdvancedTableProps) => {
58
67
  const {
59
68
  aria = {},
69
+ actions,
60
70
  children,
61
71
  className,
62
72
  columnDefinitions,
@@ -74,11 +84,14 @@ const AdvancedTable = (props: AdvancedTableProps) => {
74
84
  pagination = false,
75
85
  paginationProps,
76
86
  responsive = "scroll",
87
+ showActionsBar = true,
88
+ selectableRows,
77
89
  sortControl,
78
90
  tableData,
79
91
  tableOptions,
80
92
  tableProps,
81
93
  toggleExpansionIcon = "arrows-from-line",
94
+ onRowSelectionChange,
82
95
  } = props
83
96
 
84
97
  const [loadingStateRowCount, setLoadingStateRowCount] = useState(
@@ -96,6 +109,9 @@ const AdvancedTable = (props: AdvancedTableProps) => {
96
109
 
97
110
  const columnHelper = createColumnHelper()
98
111
 
112
+ //Row Selection
113
+ const [rowSelection, setRowSelection] = useState<RowSelectionState>({})
114
+
99
115
  //Create cells for columns, with customization for first column
100
116
  const createCellFunction = (cellAccessors: string[], customRenderer?: (row: Row<GenericObject>, value: any) => JSX.Element, index?: number) => {
101
117
  const columnCells = ({
@@ -116,6 +132,7 @@ const AdvancedTable = (props: AdvancedTableProps) => {
116
132
  getValue={getValue}
117
133
  onRowToggleClick={onRowToggleClick}
118
134
  row={row}
135
+ selectableRows={selectableRows}
119
136
  />
120
137
  )
121
138
  }
@@ -128,6 +145,7 @@ const AdvancedTable = (props: AdvancedTableProps) => {
128
145
  customRenderer={customRenderer}
129
146
  onRowToggleClick={onRowToggleClick}
130
147
  row={row}
148
+ selectableRows={selectableRows}
131
149
  value={accessorValue}
132
150
  />
133
151
  ) : (
@@ -189,9 +207,13 @@ const AdvancedTable = (props: AdvancedTableProps) => {
189
207
  },
190
208
  ]
191
209
 
192
- const expandAndSortState = () => {
193
- if (sortControl) {
210
+ const customState = () => {
211
+ if (sortControl && selectableRows) {
212
+ return { state: { expanded, sorting, rowSelection } }
213
+ } else if (sortControl) {
194
214
  return { state: { expanded, sorting } }
215
+ } else if (selectableRows) {
216
+ return { state: { expanded, rowSelection } }
195
217
  } else {
196
218
  return { state: { expanded } }
197
219
  }
@@ -219,13 +241,24 @@ const AdvancedTable = (props: AdvancedTableProps) => {
219
241
  getSortedRowModel: getSortedRowModel(),
220
242
  enableSortingRemoval: false,
221
243
  sortDescFirst: true,
222
- ...expandAndSortState(),
223
- ... paginationInitializer,
244
+ onRowSelectionChange: setRowSelection,
245
+ getRowId: selectableRows ? row => row.id : undefined,
246
+ ...customState(),
247
+ ...paginationInitializer,
224
248
  ...tableOptions,
225
249
  })
226
250
 
227
251
  const tableRows = table.getRowModel()
228
252
 
253
+ const hasAnySubRows = tableRows.rows.some(row => row.subRows && row.subRows.length > 0);
254
+ const selectedRowsLength = Object.keys(table.getState().rowSelection).length
255
+
256
+ useEffect(() => {
257
+ if (onRowSelectionChange) {
258
+ onRowSelectionChange(table.getState().rowSelection)
259
+ }
260
+ } , [table.getState().rowSelection, onRowSelectionChange])
261
+
229
262
  // Set table row count for loading state
230
263
  const updateLoadingStateRowCount = useCallback(() => {
231
264
  const rowsCount = table.getRowModel().rows.length
@@ -284,6 +317,9 @@ const AdvancedTable = (props: AdvancedTableProps) => {
284
317
  sortControl,
285
318
  table,
286
319
  toggleExpansionIcon,
320
+ showActionsBar,
321
+ selectableRows,
322
+ hasAnySubRows
287
323
  }}
288
324
  >
289
325
  <>
@@ -297,6 +333,27 @@ const AdvancedTable = (props: AdvancedTableProps) => {
297
333
  total={table.getPageCount()}
298
334
  />
299
335
  }
336
+ {
337
+ selectableRows && showActionsBar && (
338
+ <Card className="row-selection-actions-card"
339
+ padding="xs"
340
+ >
341
+ <Flex alignItems="center"
342
+ justify="between"
343
+ >
344
+ <Caption color="light"
345
+ paddingLeft="xs"
346
+ size="xs"
347
+ >
348
+ {selectedRowsLength} Selected
349
+ </Caption>
350
+ <FlexItem>
351
+ {actions}
352
+ </FlexItem>
353
+ </Flex>
354
+ </Card>
355
+ )
356
+ }
300
357
  <Table
301
358
  className={`${loading ? "content-loading" : ""}`}
302
359
  dark={dark}
@@ -1,5 +1,5 @@
1
1
  <%= pb_content_tag do %>
2
- <%= pb_rails("table", props: { size: "sm", data_table: true, number_spacing:"tabular", responsive:"none", dark: dark }) do %>
2
+ <%= pb_rails("table", props: { size: "sm", data_table: true, number_spacing:"tabular", responsive:"none", dark: dark }.merge(object.table_props)) do %>
3
3
  <% if content.present? %>
4
4
  <% content.presence %>
5
5
  <% else %>
@@ -13,6 +13,8 @@ module Playbook
13
13
  prop :responsive, type: Playbook::Props::Enum,
14
14
  values: %w[none scroll],
15
15
  default: "none"
16
+ prop :table_props, type: Playbook::Props::HashProp,
17
+ default: {}
16
18
 
17
19
  def classname
18
20
  generate_classname("pb_advanced_table", responsive_classname, separator: " ")
@@ -0,0 +1,50 @@
1
+ import React from "react"
2
+ import { AdvancedTable } from "playbook-ui"
3
+ import MOCK_DATA from "./advanced_table_mock_data_no_subrows.json"
4
+
5
+ const AdvancedTableNoSubrows = (props) => {
6
+ const columnDefinitions = [
7
+ {
8
+ accessor: "year",
9
+ label: "Year",
10
+ cellAccessors: ["quarter", "month", "day"],
11
+ },
12
+ {
13
+ accessor: "newEnrollments",
14
+ label: "New Enrollments",
15
+ },
16
+ {
17
+ accessor: "scheduledMeetings",
18
+ label: "Scheduled Meetings",
19
+ },
20
+ {
21
+ accessor: "attendanceRate",
22
+ label: "Attendance Rate",
23
+ },
24
+ {
25
+ accessor: "completedClasses",
26
+ label: "Completed Classes",
27
+ },
28
+ {
29
+ accessor: "classCompletionRate",
30
+ label: "Class Completion Rate",
31
+ },
32
+ {
33
+ accessor: "graduatedStudents",
34
+ label: "Graduated Students",
35
+ },
36
+ ]
37
+
38
+ return (
39
+ <div>
40
+ <AdvancedTable
41
+ columnDefinitions={columnDefinitions}
42
+ enableToggleExpansion="all"
43
+ tableData={MOCK_DATA}
44
+ {...props}
45
+ />
46
+ </div>
47
+ )
48
+ }
49
+
50
+ export default AdvancedTableNoSubrows
@@ -40,6 +40,7 @@ const AdvancedTablePagination = (props) => {
40
40
  <AdvancedTable
41
41
  columnDefinitions={columnDefinitions}
42
42
  pagination
43
+ responsive="none"
43
44
  tableData={PAGINATION_MOCK_DATA}
44
45
  {...props}
45
46
  />
@@ -47,6 +47,7 @@ const AdvancedTablePaginationWithProps = (props) => {
47
47
  columnDefinitions={columnDefinitions}
48
48
  pagination
49
49
  paginationProps={paginationProps}
50
+ responsive="none"
50
51
  tableData={PAGINATION_MOCK_DATA}
51
52
  {...props}
52
53
  />
@@ -0,0 +1,60 @@
1
+ import React from "react"
2
+ import { AdvancedTable } from "playbook-ui"
3
+ import MOCK_DATA from "./advanced_table_mock_data_with_id.json"
4
+
5
+ const AdvancedTableSelectableRows = (props) => {
6
+ const columnDefinitions = [
7
+ {
8
+ accessor: "year",
9
+ label: "Year",
10
+ cellAccessors: ["quarter", "month", "day"],
11
+ },
12
+ {
13
+ accessor: "newEnrollments",
14
+ label: "New Enrollments",
15
+ },
16
+ {
17
+ accessor: "scheduledMeetings",
18
+ label: "Scheduled Meetings",
19
+ },
20
+ {
21
+ accessor: "attendanceRate",
22
+ label: "Attendance Rate",
23
+ },
24
+ {
25
+ accessor: "completedClasses",
26
+ label: "Completed Classes",
27
+ },
28
+ {
29
+ accessor: "classCompletionRate",
30
+ label: "Class Completion Rate",
31
+ },
32
+ {
33
+ accessor: "graduatedStudents",
34
+ label: "Graduated Students",
35
+ },
36
+ ]
37
+
38
+ //Render the subRow header rows
39
+ const subRowHeaders = ["Quarter", "Month", "Day"]
40
+
41
+
42
+ return (
43
+ <div>
44
+ <AdvancedTable
45
+ columnDefinitions={columnDefinitions}
46
+ enableToggleExpansion="all"
47
+ onRowSelectionChange={(selectedRows) => console.log(selectedRows)}
48
+ selectableRows
49
+ tableData={MOCK_DATA}
50
+
51
+ {...props}
52
+ >
53
+ <AdvancedTable.Header />
54
+ <AdvancedTable.Body subRowHeaders={subRowHeaders}/>
55
+ </AdvancedTable>
56
+ </div>
57
+ )
58
+ }
59
+
60
+ export default AdvancedTableSelectableRows
@@ -0,0 +1,5 @@
1
+ `selectableRows` is a boolean prop that if present will add checkboxes to all rows that will allow for selecting rows.
2
+
3
+ When a parent row is clicked, it will check all nested children rows, Children rows can be manually checked or unchecked as well.
4
+
5
+ The `onRowSelectionChange` prop returns an array of ids of all Rows that have been selected. Open the console on this example and check and uncheck checkboxes to see this is action! __NOTE__: Each object within the `tableData`Array must contain a unique id in order to attach an id to all Rows for this to function.