playbook_ui 15.6.0.pre.alpha.play265012993 → 15.6.0.pre.alpha.play266913088

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 (100) hide show
  1. checksums.yaml +4 -4
  2. data/app/pb_kits/playbook/pb_advanced_table/Components/RegularTableView.tsx +3 -2
  3. data/app/pb_kits/playbook/pb_advanced_table/Components/TableHeaderCell.tsx +4 -0
  4. data/app/pb_kits/playbook/pb_advanced_table/advanced_table.test.jsx +95 -0
  5. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_background_colors_rails.html.erb +43 -0
  6. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_background_colors_rails.md +1 -0
  7. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_background_control_rails.html.erb +11 -5
  8. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_background_control_rails.md +7 -1
  9. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_styling_background.jsx +54 -0
  10. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_styling_background.md +9 -0
  11. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_styling_background_multi.jsx +80 -0
  12. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_styling_background_multi.md +3 -0
  13. data/app/pb_kits/playbook/pb_advanced_table/docs/example.yml +4 -1
  14. data/app/pb_kits/playbook/pb_advanced_table/docs/index.js +3 -1
  15. data/app/pb_kits/playbook/pb_advanced_table/table_header.html.erb +2 -2
  16. data/app/pb_kits/playbook/pb_advanced_table/table_header.rb +57 -0
  17. data/app/pb_kits/playbook/pb_bar_graph/_bar_graph.tsx +0 -6
  18. data/app/pb_kits/playbook/pb_contact/_contact.tsx +51 -24
  19. data/app/pb_kits/playbook/pb_contact/contact.html.erb +53 -19
  20. data/app/pb_kits/playbook/pb_contact/contact.rb +11 -1
  21. data/app/pb_kits/playbook/pb_contact/contact.test.js +76 -0
  22. data/app/pb_kits/playbook/pb_contact/docs/_contact_unstyled.html.erb +33 -0
  23. data/app/pb_kits/playbook/pb_contact/docs/_contact_unstyled.jsx +46 -0
  24. data/app/pb_kits/playbook/pb_contact/docs/_contact_unstyled_rails.md +2 -0
  25. data/app/pb_kits/playbook/pb_contact/docs/_contact_unstyled_react.md +2 -0
  26. data/app/pb_kits/playbook/pb_contact/docs/example.yml +2 -0
  27. data/app/pb_kits/playbook/pb_contact/docs/index.js +1 -0
  28. data/app/pb_kits/playbook/pb_date_picker/date_picker_helper.ts +16 -4
  29. data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_range_pattern_rails.html.erb +23 -14
  30. data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_range_pattern_rails.md +1 -1
  31. data/app/pb_kits/playbook/pb_dialog/_dialog.tsx +2 -1
  32. data/app/pb_kits/playbook/pb_dialog/dialog.html.erb +1 -1
  33. data/app/pb_kits/playbook/pb_dialog/dialog.rb +1 -0
  34. data/app/pb_kits/playbook/pb_dialog/dialog.test.jsx +14 -0
  35. data/app/pb_kits/playbook/pb_dialog/dialog_header.html.erb +5 -4
  36. data/app/pb_kits/playbook/pb_dialog/dialog_header.rb +2 -0
  37. data/app/pb_kits/playbook/pb_dialog/docs/_dialog_closeable.html.erb +24 -0
  38. data/app/pb_kits/playbook/pb_dialog/docs/_dialog_closeable.jsx +60 -0
  39. data/app/pb_kits/playbook/pb_dialog/docs/_dialog_closeable.md +3 -0
  40. data/app/pb_kits/playbook/pb_dialog/docs/_dialog_overflow_visible.html.erb +71 -0
  41. data/app/pb_kits/playbook/pb_dialog/docs/_dialog_overflow_visible.jsx +57 -0
  42. data/app/pb_kits/playbook/pb_dialog/docs/_dialog_overflow_visible_rails.md +1 -0
  43. data/app/pb_kits/playbook/pb_dialog/docs/_dialog_overflow_visible_react.md +1 -0
  44. data/app/pb_kits/playbook/pb_dialog/docs/example.yml +4 -0
  45. data/app/pb_kits/playbook/pb_dialog/docs/index.js +3 -1
  46. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_default_rails.html.erb +7 -5
  47. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_quickpick_default_dates.html.erb +19 -0
  48. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_quickpick_rails.html.erb +12 -0
  49. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_quickpick_rails.md +26 -0
  50. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_quickpick_range_end_rails.html.erb +19 -0
  51. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_quickpick_range_end_rails.md +1 -0
  52. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_quickpick_with_date_pickers_default_rails.html.erb +30 -0
  53. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_quickpick_with_date_pickers_default_rails.md +3 -0
  54. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_quickpick_with_date_pickers_rails.html.erb +29 -0
  55. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_quickpick_with_date_pickers_rails.md +13 -0
  56. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_display_rails.html.erb +3 -1
  57. data/app/pb_kits/playbook/pb_dropdown/docs/example.yml +5 -0
  58. data/app/pb_kits/playbook/pb_dropdown/dropdown.html.erb +4 -0
  59. data/app/pb_kits/playbook/pb_dropdown/dropdown.rb +39 -5
  60. data/app/pb_kits/playbook/pb_dropdown/index.js +171 -3
  61. data/app/pb_kits/playbook/pb_dropdown/quickpick_helper.rb +75 -0
  62. data/app/pb_kits/playbook/pb_filter/Filter/FilterBackground.tsx +3 -3
  63. data/app/pb_kits/playbook/pb_legend/_legend.tsx +1 -6
  64. data/app/pb_kits/playbook/pb_legend/legend.html.erb +0 -1
  65. data/app/pb_kits/playbook/pb_table/_table.tsx +187 -33
  66. data/app/pb_kits/playbook/pb_table/docs/_table_with_filter_variant.jsx +134 -0
  67. data/app/pb_kits/playbook/pb_table/docs/_table_with_filter_variant.md +34 -0
  68. data/app/pb_kits/playbook/pb_table/docs/_table_with_filter_variant_rails.html.erb +101 -0
  69. data/app/pb_kits/playbook/pb_table/docs/_table_with_filter_variant_rails.md +33 -0
  70. data/app/pb_kits/playbook/pb_table/docs/_table_with_filter_variant_with_pagination.jsx +180 -0
  71. data/app/pb_kits/playbook/pb_table/docs/_table_with_filter_variant_with_pagination.md +3 -0
  72. data/app/pb_kits/playbook/pb_table/docs/_table_with_filter_variant_with_pagination_rails.html.erb +122 -0
  73. data/app/pb_kits/playbook/pb_table/docs/_table_with_filter_variant_with_pagination_rails.md +3 -0
  74. data/app/pb_kits/playbook/pb_table/docs/example.yml +4 -0
  75. data/app/pb_kits/playbook/pb_table/docs/index.js +2 -0
  76. data/app/pb_kits/playbook/pb_table/table.html.erb +68 -12
  77. data/app/pb_kits/playbook/pb_table/table.rb +22 -3
  78. data/app/pb_kits/playbook/pb_table/table.test.js +143 -0
  79. data/app/pb_kits/playbook/pb_timeline/_item.tsx +3 -0
  80. data/app/pb_kits/playbook/pb_timeline/docs/_timeline_show_current_year.html.erb +60 -0
  81. data/app/pb_kits/playbook/pb_timeline/docs/_timeline_show_current_year.jsx +118 -0
  82. data/app/pb_kits/playbook/pb_timeline/docs/_timeline_show_current_year.md +1 -0
  83. data/app/pb_kits/playbook/pb_timeline/docs/_timeline_with_date.md +1 -1
  84. data/app/pb_kits/playbook/pb_timeline/docs/example.yml +2 -0
  85. data/app/pb_kits/playbook/pb_timeline/docs/index.js +1 -0
  86. data/app/pb_kits/playbook/pb_timeline/item.html.erb +1 -1
  87. data/app/pb_kits/playbook/pb_timeline/item.rb +2 -0
  88. data/app/pb_kits/playbook/pb_timeline/label.html.erb +2 -1
  89. data/app/pb_kits/playbook/pb_timeline/label.rb +2 -0
  90. data/app/pb_kits/playbook/pb_timeline/subcomponents/Label.tsx +3 -0
  91. data/app/pb_kits/playbook/pb_timeline/timeline.test.js +51 -0
  92. data/dist/chunks/_typeahead-CbjBmIDu.js +6 -0
  93. data/dist/chunks/{lib-DDDLiZuu.js → lib-DxDBrGZX.js} +3 -3
  94. data/dist/chunks/vendor.js +3 -3
  95. data/dist/menu.yml +3 -4
  96. data/dist/playbook-rails-react-bindings.js +1 -1
  97. data/dist/playbook-rails.js +1 -1
  98. data/lib/playbook/version.rb +1 -1
  99. metadata +42 -4
  100. data/dist/chunks/_typeahead-DMyvWpig.js +0 -6
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Playbook
4
+ module PbDropdown
5
+ module QuickpickHelper
6
+ class << self
7
+ def get_quickpick_options(range_ends_today: false)
8
+ today = Date.today
9
+ yesterday = today - 1.day
10
+
11
+ this_week_start_date = first_day_of_week(today)
12
+ this_week_end_date = range_ends_today ? today : last_day_of_week(today)
13
+ last_week_start_date = previous_week_start_date(today)
14
+ last_week_end_date = previous_week_end_date(today)
15
+
16
+ this_month_start_date = today.beginning_of_month
17
+ this_month_end_date = range_ends_today ? today : today.end_of_month
18
+ last_month_start_date = (today - 1.month).beginning_of_month
19
+ last_month_end_date = (today - 1.month).end_of_month
20
+
21
+ this_quarter_start_date = today.beginning_of_quarter
22
+ this_quarter_end_date = range_ends_today ? today : today.end_of_quarter
23
+ last_quarter_start_date = (today - 3.months).beginning_of_quarter
24
+ last_quarter_end_date = (today - 3.months).end_of_quarter
25
+
26
+ this_year_start_date = today.beginning_of_year
27
+ this_year_end_date = range_ends_today ? today : today.end_of_year
28
+ last_year_start_date = (today - 1.year).beginning_of_year
29
+ last_year_end_date = (today - 1.year).end_of_year
30
+
31
+ [
32
+ { id: "quickpick-today", label: "Today", value: [today.to_s, today.to_s], formatted_start_date: format_date(today), formatted_end_date: format_date(today) },
33
+ { id: "quickpick-yesterday", label: "Yesterday", value: [yesterday.to_s, yesterday.to_s], formatted_start_date: format_date(yesterday), formatted_end_date: format_date(yesterday) },
34
+ { id: "quickpick-this-week", label: "This Week", value: [this_week_start_date.to_s, this_week_end_date.to_s], formatted_start_date: format_date(this_week_start_date), formatted_end_date: format_date(this_week_end_date) },
35
+ { id: "quickpick-this-month", label: "This Month", value: [this_month_start_date.to_s, this_month_end_date.to_s], formatted_start_date: format_date(this_month_start_date), formatted_end_date: format_date(this_month_end_date) },
36
+ { id: "quickpick-this-quarter", label: "This Quarter", value: [this_quarter_start_date.to_s, this_quarter_end_date.to_s], formatted_start_date: format_date(this_quarter_start_date), formatted_end_date: format_date(this_quarter_end_date) },
37
+ { id: "quickpick-this-year", label: "This Year", value: [this_year_start_date.to_s, this_year_end_date.to_s], formatted_start_date: format_date(this_year_start_date), formatted_end_date: format_date(this_year_end_date) },
38
+ { id: "quickpick-last-week", label: "Last Week", value: [last_week_start_date.to_s, last_week_end_date.to_s], formatted_start_date: format_date(last_week_start_date), formatted_end_date: format_date(last_week_end_date) },
39
+ { id: "quickpick-last-month", label: "Last Month", value: [last_month_start_date.to_s, last_month_end_date.to_s], formatted_start_date: format_date(last_month_start_date), formatted_end_date: format_date(last_month_end_date) },
40
+ { id: "quickpick-last-quarter", label: "Last Quarter", value: [last_quarter_start_date.to_s, last_quarter_end_date.to_s], formatted_start_date: format_date(last_quarter_start_date), formatted_end_date: format_date(last_quarter_end_date) },
41
+ { id: "quickpick-last-year", label: "Last Year", value: [last_year_start_date.to_s, last_year_end_date.to_s], formatted_start_date: format_date(last_year_start_date), formatted_end_date: format_date(last_year_end_date) },
42
+ ]
43
+ end
44
+
45
+ private
46
+
47
+ def format_date(date)
48
+ date.strftime("%m/%d/%Y")
49
+ end
50
+
51
+ def format_date_range(start_date, end_date)
52
+ "#{format_date(start_date)} - #{format_date(end_date)}"
53
+ end
54
+
55
+ def first_day_of_week(date)
56
+ # Monday as first day of week
57
+ date.beginning_of_week(:monday)
58
+ end
59
+
60
+ def last_day_of_week(date)
61
+ # Sunday as last day of week
62
+ date.end_of_week(:monday)
63
+ end
64
+
65
+ def previous_week_start_date(date)
66
+ first_day_of_week(date) - 1.week
67
+ end
68
+
69
+ def previous_week_end_date(date)
70
+ last_day_of_week(date) - 1.week
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -6,10 +6,10 @@ import { GlobalProps, globalProps } from '../../utilities/globalProps'
6
6
  import Card from '../../pb_card/_card'
7
7
 
8
8
  export type FilterBackgroundProps = {
9
- background: boolean,
10
- className: string,
9
+ background?: boolean,
10
+ className?: string,
11
11
  children?: React.ReactChild[] | React.ReactChild,
12
- dark: boolean,
12
+ dark?: boolean,
13
13
  } & GlobalProps
14
14
 
15
15
  const FilterBackground = (props: FilterBackgroundProps): React.ReactElement => {
@@ -1,9 +1,8 @@
1
- import React, { useEffect } from 'react'
1
+ import React from 'react'
2
2
  import classnames from 'classnames'
3
3
 
4
4
  import { buildAriaProps, buildCss, buildDataProps, buildHtmlProps } from '../utilities/props'
5
5
  import { globalProps } from '../utilities/globalProps'
6
- import { deprecatedKitWarning } from '../utilities/deprecated'
7
6
 
8
7
  import Body from '../pb_body/_body'
9
8
  import Title from '../pb_title/_title'
@@ -33,10 +32,6 @@ const Legend = (props: LegendProps) => {
33
32
  text,
34
33
  } = props
35
34
 
36
- useEffect(() => {
37
- deprecatedKitWarning('Legend')
38
- }, [])
39
-
40
35
  const ariaProps = buildAriaProps(aria)
41
36
  const dataProps = buildDataProps(data)
42
37
  const htmlProps = buildHtmlProps(htmlOptions)
@@ -1,4 +1,3 @@
1
- <%== deprecated_kit_warning('Legend') %>
2
1
  <%= pb_content_tag do %>
3
2
  <%= pb_rails("body", props: {color: object.body_color}) do %>
4
3
  <span style="<%= object.custom_color %>" class=<%= object.custom_color_class %>></span>
@@ -10,6 +10,11 @@ import {
10
10
  TableCell,
11
11
  } from "./subcomponents";
12
12
  import { addDataTitle } from './utilities/addDataTitle'
13
+ import Card from '../pb_card/_card'
14
+ import Flex from '../pb_flex/_flex'
15
+ import Title from '../pb_title/_title'
16
+ import SectionSeparator from '../pb_section_separator/_section_separator'
17
+ import Filter from '../pb_filter/_filter'
13
18
 
14
19
  type TableProps = {
15
20
  aria?: { [key: string]: string },
@@ -21,10 +26,13 @@ type TableProps = {
21
26
  data?: { [key: string]: string },
22
27
  dataTable: boolean,
23
28
  disableHover?: boolean,
29
+ filterProps?: { [key: string]: any },
30
+ filterContent?: any,
24
31
  headerStyle?: "default" | "borderless" | "floating"
25
32
  htmlOptions?: { [key: string]: string | number | boolean | (() => void) },
26
33
  id?: string,
27
34
  outerPadding?: "none" | "xxs" | "xs" | "sm" | "md" | "lg" | "xl",
35
+ pagination?: React.ReactElement,
28
36
  responsive?: "collapse" | "scroll" | "none",
29
37
  singleLine?: boolean,
30
38
  size?: "sm" | "md" | "lg",
@@ -33,24 +41,32 @@ type TableProps = {
33
41
  stickyRightColumn?: string[],
34
42
  striped?: boolean,
35
43
  tag?: "table" | "div",
44
+ title?: string,
45
+ variant?: "default" | "withFilter",
36
46
  verticalBorder?: boolean,
37
47
  } & GlobalProps
38
48
 
49
+ type AllSizes = "none" | "xxs" | "xs" | "sm" | "md" | "lg" | "xl" | "xxl" | "auto" | "initial" | "inherit"
50
+
39
51
  const Table = (props: TableProps): React.ReactElement => {
40
52
  const {
41
53
  aria = {},
54
+ variant = 'default',
42
55
  children,
43
56
  className,
44
- collapse = 'sm',
57
+ collapse = variant === 'withFilter' ? 'md' : 'sm',
45
58
  container = true,
46
59
  dark,
47
60
  data = {},
48
61
  dataTable = false,
49
62
  disableHover = false,
63
+ filterProps = {},
64
+ filterContent,
50
65
  headerStyle = "default",
51
66
  htmlOptions = {},
52
67
  id,
53
68
  outerPadding = '',
69
+ pagination,
54
70
  responsive = 'collapse',
55
71
  singleLine = false,
56
72
  size = 'sm',
@@ -59,6 +75,7 @@ const Table = (props: TableProps): React.ReactElement => {
59
75
  stickyRightColumn= [],
60
76
  striped = false,
61
77
  tag = 'table',
78
+ title,
62
79
  verticalBorder = false,
63
80
  } = props
64
81
 
@@ -73,12 +90,15 @@ const Table = (props: TableProps): React.ReactElement => {
73
90
  const dynamicInlineProps = globalInlineProps(props)
74
91
  const stickyRightColumnReversed = stickyRightColumn.reverse()
75
92
 
93
+ const isFilterVariant = variant === 'withFilter'
94
+ const effectiveContainer = isFilterVariant ? false : container
95
+
76
96
  const classNames = classnames(
77
97
  'pb_table',
78
98
  `table-${size}`,
79
99
  `table-responsive-${responsive}`,
80
100
  {
81
- 'table-card': container,
101
+ 'table-card': effectiveContainer,
82
102
  'table-dark': dark,
83
103
  'data_table': dataTable,
84
104
  'single-line': singleLine,
@@ -205,36 +225,70 @@ const Table = (props: TableProps): React.ReactElement => {
205
225
  addDataTitle()
206
226
  }, [])
207
227
 
208
- return (
209
- <>
210
- {responsive === 'scroll' ? (
211
- <div className='table-responsive-scroll'>
212
- {isTableTag ? (
213
- <table
214
- {...ariaProps}
215
- {...dataProps}
216
- {...htmlProps}
217
- className={classNames}
218
- id={id}
219
- style={dynamicInlineProps}
220
- >
221
- {children}
222
- </table>
223
- ) : (
224
- <div
225
- {...ariaProps}
226
- {...dataProps}
227
- {...htmlProps}
228
- className={classNames}
229
- id={id}
230
- style={dynamicInlineProps}
231
- >
232
- {children}
233
- </div>
234
- )}
235
- </div>
228
+ // ------------ Default Table (non-filter variant rendering) ------------
229
+ const renderTable = () => {
230
+ const tableElement = responsive === 'scroll' ? (
231
+ <div className='table-responsive-scroll'>
232
+ {isTableTag ? (
233
+ <table
234
+ {...ariaProps}
235
+ {...dataProps}
236
+ {...htmlProps}
237
+ className={classNames}
238
+ id={id}
239
+ style={dynamicInlineProps}
240
+ >
241
+ {children}
242
+ </table>
243
+ ) : (
244
+ <div
245
+ {...ariaProps}
246
+ {...dataProps}
247
+ {...htmlProps}
248
+ className={classNames}
249
+ id={id}
250
+ style={dynamicInlineProps}
251
+ >
252
+ {children}
253
+ </div>
254
+ )}
255
+ </div>
256
+ ) : (
257
+ isTableTag ? (
258
+ <table
259
+ {...ariaProps}
260
+ {...dataProps}
261
+ {...htmlProps}
262
+ className={classNames}
263
+ id={id}
264
+ style={dynamicInlineProps}
265
+ >
266
+ {children}
267
+ </table>
236
268
  ) : (
237
- isTableTag ? (
269
+ <div
270
+ {...ariaProps}
271
+ {...dataProps}
272
+ {...htmlProps}
273
+ className={classNames}
274
+ id={id}
275
+ style={dynamicInlineProps}
276
+ >
277
+ {children}
278
+ </div>
279
+ )
280
+ )
281
+
282
+ return tableElement
283
+ }
284
+ // ------------ End Default Table (non-filter variant rendering) ------------
285
+
286
+ // ------------ variant = 'withFilter' rendering ------------
287
+ const renderCardVariant = () => {
288
+ // Render table element
289
+ const tableElement = responsive === 'scroll' ? (
290
+ <div className='table-responsive-scroll'>
291
+ {isTableTag ? (
238
292
  <table
239
293
  {...ariaProps}
240
294
  {...dataProps}
@@ -256,8 +310,108 @@ const Table = (props: TableProps): React.ReactElement => {
256
310
  >
257
311
  {children}
258
312
  </div>
259
- )
260
- )}
313
+ )}
314
+ </div>
315
+ ) : (
316
+ isTableTag ? (
317
+ <table
318
+ {...ariaProps}
319
+ {...dataProps}
320
+ {...htmlProps}
321
+ className={classNames}
322
+ id={id}
323
+ style={dynamicInlineProps}
324
+ >
325
+ {children}
326
+ </table>
327
+ ) : (
328
+ <div
329
+ {...ariaProps}
330
+ {...dataProps}
331
+ {...htmlProps}
332
+ className={classNames}
333
+ id={id}
334
+ style={dynamicInlineProps}
335
+ >
336
+ {children}
337
+ </div>
338
+ )
339
+ )
340
+
341
+ // Default filter props that CAN be overridden (All props from Filter kit CAN be used, but these are the ones we set as defaults)
342
+ const defaultFilterProps = {
343
+ background: false,
344
+ maxHeight: "50vh",
345
+ minWidth: "xs",
346
+ popoverProps: { width: "350px" },
347
+ }
348
+
349
+ // Merge default props with user-provided props (user props override defaults)
350
+ const mergedFilterProps = { ...defaultFilterProps, ...filterProps }
351
+
352
+ return (
353
+ <>
354
+ {title && (
355
+ <Title
356
+ paddingLeft={{
357
+ xs: "sm",
358
+ sm: "sm",
359
+ md: "xl",
360
+ lg: "xl",
361
+ xl: "xl",
362
+ default: "xl",
363
+ } as any}
364
+ paddingY="md"
365
+ size={3}
366
+ text={title}
367
+ />
368
+ )}
369
+ <Card
370
+ marginX={{
371
+ xs: "sm",
372
+ sm: "sm",
373
+ md: "xl",
374
+ lg: "xl",
375
+ xl: "xl",
376
+ default: "xl",
377
+ } as any}
378
+ padding="none"
379
+ >
380
+ <Flex
381
+ align="stretch"
382
+ flexDirection="column"
383
+ gap="none"
384
+ >
385
+ {filterContent && (
386
+ <Filter {...mergedFilterProps}>
387
+ {filterContent}
388
+ </Filter>
389
+ )}
390
+ {filterContent && <SectionSeparator />}
391
+ {pagination && (
392
+ <>
393
+ {pagination}
394
+ <SectionSeparator />
395
+ </>
396
+ )}
397
+ {tableElement}
398
+ {pagination && (
399
+ <>
400
+ {pagination}
401
+ </>
402
+ )}
403
+ </Flex>
404
+ </Card>
405
+ </>
406
+ )
407
+ }
408
+ // ------------ End variant = 'withFilter' rendering ------------
409
+
410
+
411
+
412
+ return (
413
+ <>
414
+ {isFilterVariant ? renderCardVariant() : renderTable()}
261
415
  </>
262
416
  )
263
417
  }
@@ -0,0 +1,134 @@
1
+ import React, { useState } from "react"
2
+ import { Button, Date as DateKit, DatePicker, Dropdown, Select, Table, TextInput, Typeahead, Flex } from "playbook-ui"
3
+
4
+ // Mock Data for Table
5
+ const users = [
6
+ { id: 1, name: "Jennifer", title: "Associate Scrum Master", department: "Business Technology", branch: "Philadelphia", startDate: "2025-01-01" },
7
+ { id: 2, name: "Nick", title: "UX Engineer II", department: "Business Technology", branch: "Philadelphia", startDate: "2025-01-02" },
8
+ { id: 3, name: "Nida", title: "Senior UX Engineer", department: "Business Technology", branch: "Philadelphia", startDate: "2025-01-03" },
9
+ { id: 4, name: "Justin", title: "Director of User Experience Engineering", department: "Business Technology", branch: "Philadelphia", startDate: "2025-01-04" },
10
+ { id: 5, name: "Edward", title: "UX Designer II", department: "Business Technology", branch: "Philadelphia", startDate: "2025-01-05" },
11
+ { id: 6, name: "Elisa", title: "UX Engineer", department: "Business Technology", branch: "Philadelphia", startDate: "2025-01-06" },
12
+ { id: 7, name: "Gary", title: "UX Engineer", department: "Business Technology", branch: "Philadelphia", startDate: "2025-01-07" },
13
+ { id: 8, name: "Barkley", title: "Nitro Quality Ninja", department: "Business Technology", branch: "Philadelphia", startDate: "2025-01-08" },
14
+ { id: 9, name: "Aaron", title: "Associate Nitro Quality Ninja", department: "Business Technology", branch: "Philadelphia", startDate: "2025-01-09" },
15
+ ]
16
+
17
+ const TableWithFilterVariant = () => {
18
+ const [territory, setTerritory] = useState("")
19
+
20
+ // --------Filter content example ------
21
+ const filterContent = ({ closePopover }) => (
22
+ <>
23
+ <TextInput
24
+ label="Territory ID"
25
+ onChange={event => setTerritory(event.target.value)}
26
+ value={territory}
27
+ />
28
+
29
+ <Typeahead
30
+ label="Title"
31
+ options={[
32
+ { key: "senior-ux-engineer", label: "Senior UX Engineer", value: "senior-ux-engineer" },
33
+ { key: "ux-engineer", label: "UX Engineer", value: "ux-engineer" },
34
+ { key: "ux-designer", label: "UX Designer", value: "ux-designer" }
35
+ ]}
36
+ />
37
+
38
+ <Select
39
+ blankSelection="All Departments"
40
+ label="Department"
41
+ options={[
42
+ { value: "Business Technology", label: "Business Technology", key: "business-technology" },
43
+ { value: "Customer Development", label: "Customer Development", key: "customer-development" },
44
+ { value: "Talent Acquisition", label: "Talent Acquisition", key: "talent-acquisition" }
45
+ ]}
46
+ />
47
+
48
+ <Dropdown
49
+ label="Branch"
50
+ options={[
51
+ { key: "Philadelphia", label: "Philadelphia", value: "philadelphia" },
52
+ { key: "New York", label: "New York", value: "new-york" },
53
+ { key: "Austin", label: "Austin", value: "austin" }
54
+ ]}
55
+ />
56
+
57
+ <DatePicker
58
+ label="Start Date"
59
+ paddingY="sm"
60
+ pickerId="startedOn"
61
+ />
62
+ <Flex spacing="between">
63
+ <Button
64
+ onClick={() => {
65
+ alert("No filtering functionality - just a pattern demo!")
66
+ closePopover()
67
+ }}
68
+ text="Filter"
69
+ />
70
+ <Button
71
+ text="Defaults"
72
+ variant="secondary"
73
+ />
74
+ </Flex>
75
+ </>
76
+ )
77
+ // -------End Filter content example ------
78
+
79
+ return (
80
+ <Table
81
+ filterContent={filterContent}
82
+ filterProps={{
83
+ results: 50,
84
+ sortOptions: {
85
+ territory_id: "Territory ID",
86
+ first_name: "Name",
87
+ started_on: "Start Date",
88
+ department_name: "Department",
89
+ title_name: "Title",
90
+ branch_branch_name: "Branch",
91
+ },
92
+ sortValue: [{ name: 'started_on', dir: 'asc' }],
93
+ }}
94
+ title="Table Title Here"
95
+ variant="withFilter"
96
+ >
97
+ <Table.Head>
98
+ <Table.Row>
99
+ <Table.Header>{'Territory ID'}</Table.Header>
100
+ <Table.Header>{'Name'}</Table.Header>
101
+ <Table.Header>{'Title'}</Table.Header>
102
+ <Table.Header>{'Department'}</Table.Header>
103
+ <Table.Header>{'Branch'}</Table.Header>
104
+ <Table.Header textAlign="right">{'Start Date'}</Table.Header>
105
+ </Table.Row>
106
+ </Table.Head>
107
+ <Table.Body>
108
+ {users.map((user) => (
109
+ <Table.Row key={user.id}>
110
+ <Table.Cell
111
+ marginX={{ xs: "sm" }}
112
+ numberSpacing="tabular"
113
+ >
114
+ {user.id}
115
+ </Table.Cell>
116
+ <Table.Cell marginX={{ xs: "sm" }}>{user.name}</Table.Cell>
117
+ <Table.Cell marginX={{ xs: "sm" }}>{user.title}</Table.Cell>
118
+ <Table.Cell marginX={{ xs: "sm" }}>{user.department}</Table.Cell>
119
+ <Table.Cell marginX={{ xs: "sm" }}>{user.branch}</Table.Cell>
120
+ <Table.Cell marginX={{ xs: "sm" }}>
121
+ <DateKit
122
+ alignment="right"
123
+ showCurrentYear
124
+ value={user.startDate}
125
+ />
126
+ </Table.Cell>
127
+ </Table.Row>
128
+ ))}
129
+ </Table.Body>
130
+ </Table>
131
+ )
132
+ }
133
+
134
+ export default TableWithFilterVariant
@@ -0,0 +1,34 @@
1
+ Set the `variant` prop to `withFilter` to render a Table with a filter. The variant automatically handles:
2
+
3
+ - Card wrapper with standard responsive margins
4
+ - Optional `title` prop to render title above the card
5
+ - Filter component rendering with Design defaults
6
+ - SectionSeparator between filter and table
7
+ - Flex layout for proper alignment
8
+
9
+ #### Required Props
10
+
11
+ - `variant="withFilter"`: Enables the filter variant
12
+ - `filterContent`: A function that receives `{ closePopover }` and returns the filter's body content (inputs, buttons, etc.). Use this to pass in all input kits, etc needed inside the Filter itself.
13
+ - `filterProps`: An object containing Filter-specific props like `results`, `sortOptions`, `sortValue`, etc.
14
+
15
+ #### Optional Props
16
+
17
+ - `title`: Displays a title above the card
18
+ - All standard Table props (`size`, `collapse`, etc.) can be used, but defaults are already set to match Design guidelines
19
+ - All standard Filter props can be used, but defaults are already set to match Design guidelines.
20
+
21
+ #### Default Filter Props
22
+
23
+ The Table kit automatically sets these Filter defaults (which you can override via `filterProps`):
24
+
25
+ - `background={false}`
26
+ - `maxHeight="50vh"`
27
+ - `minWidth="xs"`
28
+ - `popoverProps={{ width: "350px" }}`
29
+
30
+
31
+ **IMPORTANT NOTE**:
32
+ The purpose of this variant is to provide an easy way to set up a Table with a Filter with Design standards applied by default.
33
+
34
+ If you are looking for more customization than this embedded variant provides, you may be better served by using the individual kits as demonstrated in our Table Filter Card Building Block [here](https://playbook.powerapp.cloud/building_blocks/table_filter_card/react).