playbook_ui 14.14.0.pre.rc.5 → 14.14.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.scss +3 -0
  3. data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.tsx +6 -5
  4. data/app/pb_kits/playbook/pb_advanced_table/advanced_table.rb +8 -1
  5. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_headers_custom_cell.jsx +75 -0
  6. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_table_props.html.erb +1 -1
  7. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_table_props_rails.md +3 -1
  8. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_table_props_react.md +1 -1
  9. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_table_props_sticky_header.html.erb +33 -0
  10. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_table_props_sticky_header_rails.md +3 -0
  11. data/app/pb_kits/playbook/pb_advanced_table/docs/example.yml +2 -0
  12. data/app/pb_kits/playbook/pb_advanced_table/docs/index.js +2 -1
  13. data/app/pb_kits/playbook/pb_checkbox/_checkbox.tsx +17 -8
  14. data/app/pb_kits/playbook/pb_checkbox/checkbox.test.js +16 -0
  15. data/app/pb_kits/playbook/pb_checkbox/docs/_checkbox_react_hook.jsx +69 -0
  16. data/app/pb_kits/playbook/pb_checkbox/docs/_checkbox_react_hook.md +1 -0
  17. data/app/pb_kits/playbook/pb_checkbox/docs/example.yml +2 -1
  18. data/app/pb_kits/playbook/pb_checkbox/docs/index.js +1 -0
  19. data/app/pb_kits/playbook/pb_overlay/_overlay.tsx +4 -0
  20. data/app/pb_kits/playbook/pb_overlay/docs/_overlay_vertical_dynamic_multi_directional.jsx +37 -0
  21. data/app/pb_kits/playbook/pb_overlay/docs/_overlay_vertical_dynamic_multi_directional_react.md +1 -0
  22. data/app/pb_kits/playbook/pb_overlay/docs/example.yml +1 -0
  23. data/app/pb_kits/playbook/pb_overlay/docs/index.js +1 -0
  24. data/app/pb_kits/playbook/pb_overlay/subcomponents/_overlay_token.tsx +48 -10
  25. data/app/pb_kits/playbook/pb_progress_pills/progress_pills.html.erb +1 -6
  26. data/app/pb_kits/playbook/pb_progress_simple/progress_simple.html.erb +1 -5
  27. data/app/pb_kits/playbook/pb_progress_step/progress_step.html.erb +1 -5
  28. data/app/pb_kits/playbook/pb_progress_step/progress_step_item.html.erb +1 -5
  29. data/app/pb_kits/playbook/pb_radio/radio.html.erb +6 -11
  30. data/dist/chunks/{_typeahead-CAIQfP7X.js → _typeahead-PqkcDf1H.js} +2 -2
  31. data/dist/chunks/_weekday_stacked-B_pw5Znc.js +45 -0
  32. data/dist/chunks/lazysizes-DHz07jlL.js +1 -0
  33. data/dist/chunks/vendor.js +1 -1
  34. data/dist/playbook-doc.js +1 -1
  35. data/dist/playbook-rails-react-bindings.js +1 -1
  36. data/dist/playbook-rails.js +1 -1
  37. data/dist/playbook.css +1 -1
  38. data/lib/playbook/version.rb +1 -1
  39. metadata +12 -5
  40. data/dist/chunks/_weekday_stacked-DstwbGUv.js +0 -45
  41. data/dist/chunks/lazysizes-B7xYodB-.js +0 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5a78bc366f1f7086a31c4095eb10e5c5ee0be08a56c68327597848a0d7a9236a
4
- data.tar.gz: 83701efa1b7889f3359c4e73dde11ce3f2a48d5ec39e42d5c550f5c6299aeb38
3
+ metadata.gz: 17877ba581eff6413e953e73d723ec75abe81b10acb06296ed5ef7d2d2660b3b
4
+ data.tar.gz: 4af889ae0187e654b33e723c6f1f0b4b35b42a65b8918bb2e13c4ffd6ad55d58
5
5
  SHA512:
6
- metadata.gz: a51f1c37116779e420d0a30abe9aa0617d611103fdb5bf1e44aa3639be7e4d09ab61d71ea2e29173dc6a144110a262eaf7a27370c110db5926d24b80a20d870f
7
- data.tar.gz: 4dceab2450821e9c3b12a791d4b919d747341b7b73fca55b83ff18fa6c460a0e39204a0d7bd3757b2bd53b46ad37af9a5624222e897e0ffe1f2f5d12938b9c4d
6
+ metadata.gz: a1d75c334c43dc1f3c1404905752d0a58dc3ef935878c9bbc7c5ad1435de8659a2fa133585cdcbac1d076458bec5c6d3e20deae169657d06be9a01eb0bb011ed
7
+ data.tar.gz: a73590f43aad9c9bf7e6abdef9ca99741ef848d32a77287e147af26c334dbf0d79c487437217f02272748a476d906e34e4a4d3ee25b28c5cf5e2e51e4640b8f4
@@ -268,6 +268,9 @@
268
268
  box-shadow: 1px 0 10px -2px $border_light !important;
269
269
  }
270
270
  }
271
+ .pb_advanced_table_header {
272
+ box-shadow: none !important;
273
+ }
271
274
  }
272
275
  }
273
276
  }
@@ -116,7 +116,7 @@ const AdvancedTable = (props: AdvancedTableProps) => {
116
116
  const [rowSelection, setRowSelection] = useState<RowSelectionState>({})
117
117
 
118
118
  //Create cells for columns, with customization for first column
119
- const createCellFunction = (cellAccessors: string[], customRenderer?: (row: Row<GenericObject>, value: any) => JSX.Element, index?: number) => {
119
+ const createCellFunction = (cellAccessors: string[], customRenderer?: (row: Row<GenericObject>, value: any) => JSX.Element, isFirstColumn?: boolean) => {
120
120
  const columnCells = ({
121
121
  row,
122
122
  getValue,
@@ -126,7 +126,7 @@ const AdvancedTable = (props: AdvancedTableProps) => {
126
126
  }) => {
127
127
  const rowData = row.original
128
128
 
129
- if (index === 0) {
129
+ if (isFirstColumn) {
130
130
  switch (row.depth) {
131
131
  case 0: {
132
132
  return (
@@ -164,15 +164,16 @@ const AdvancedTable = (props: AdvancedTableProps) => {
164
164
  return columnCells
165
165
  }
166
166
 
167
- const buildColumns = (columnDefinitions: GenericObject[]): any => {
167
+ const buildColumns = (columnDefinitions: GenericObject[], isRoot= true): any => {
168
168
  return (
169
169
  columnDefinitions &&
170
170
  columnDefinitions.map((column, index) => {
171
+ const isFirstColumn = isRoot && index === 0;
171
172
  //Checking to see if grouped column or not
172
173
  if (column.columns && column.columns.length > 0) {
173
174
  return {
174
175
  header: column.label || "",
175
- columns: buildColumns(column.columns),
176
+ columns: buildColumns(column.columns, false),
176
177
  };
177
178
  } else {
178
179
  // Define the base column structure
@@ -186,7 +187,7 @@ const AdvancedTable = (props: AdvancedTableProps) => {
186
187
  columnStructure.cell = createCellFunction(
187
188
  column.cellAccessors,
188
189
  column.customRenderer,
189
- index
190
+ isFirstColumn
190
191
  );
191
192
  }
192
193
 
@@ -17,14 +17,21 @@ module Playbook
17
17
  default: "scroll"
18
18
  prop :table_props, type: Playbook::Props::HashProp,
19
19
  default: {}
20
+ prop :max_height, type: Playbook::Props::Enum,
21
+ values: %w[auto xs sm md lg xl xxl xxxl],
22
+ default: "auto"
20
23
 
21
24
  def classname
22
- generate_classname("pb_advanced_table", responsive_classname, separator: " ")
25
+ generate_classname("pb_advanced_table", responsive_classname, max_height_classname, separator: " ")
23
26
  end
24
27
 
25
28
  def responsive_classname
26
29
  responsive == "scroll" ? "advanced-table-responsive-scroll" : "advanced-table-responsive-none"
27
30
  end
31
+
32
+ def max_height_classname
33
+ max_height.present? ? "advanced-table-max-height-#{max_height}" : ""
34
+ end
28
35
  end
29
36
  end
30
37
  end
@@ -0,0 +1,75 @@
1
+ import React from "react"
2
+ import { AdvancedTable, Pill } from "playbook-ui"
3
+ import MOCK_DATA from "./advanced_table_mock_data.json"
4
+
5
+ const AdvancedTableColumnHeadersCustomCell = (props) => {
6
+ const columnDefinitions = [
7
+ {
8
+ accessor: "year",
9
+ label: "Year",
10
+ cellAccessors: ["quarter", "month", "day"],
11
+ },
12
+ {
13
+ label: "Enrollment Data",
14
+ columns: [
15
+ {
16
+ accessor: "newEnrollments",
17
+ label: "New Enrollments",
18
+ customRenderer: (row, value) => (
19
+ <Pill text={value}
20
+ variant="success"
21
+ />
22
+ ),
23
+ },
24
+ {
25
+ accessor: "scheduledMeetings",
26
+ label: "Scheduled Meetings",
27
+ customRenderer: (row, value) => (
28
+ <Pill text={value}
29
+ variant="info"
30
+ />
31
+ ),
32
+ },
33
+ ],
34
+ },
35
+ {
36
+ label: "Performance Data",
37
+ columns: [
38
+ {
39
+ accessor: "attendanceRate",
40
+ label: "Attendance Rate",
41
+ },
42
+ {
43
+ accessor: "completedClasses",
44
+ label: "Completed Classes",
45
+ customRenderer: (row, value) => (
46
+ <Pill text={value}
47
+ variant="error"
48
+ />
49
+ ),
50
+ },
51
+ {
52
+ accessor: "classCompletionRate",
53
+ label: "Class Completion Rate",
54
+ },
55
+ {
56
+ accessor: "graduatedStudents",
57
+ label: "Graduated Students",
58
+ },
59
+ ],
60
+ },
61
+ ];
62
+
63
+
64
+ return (
65
+ <>
66
+ <AdvancedTable
67
+ columnDefinitions={columnDefinitions}
68
+ tableData={MOCK_DATA}
69
+ {...props}
70
+ />
71
+ </>
72
+ )
73
+ }
74
+
75
+ export default AdvancedTableColumnHeadersCustomCell
@@ -30,4 +30,4 @@
30
30
  }
31
31
  ] %>
32
32
 
33
- <%= pb_rails("advanced_table", props: { id: "table_props_table", table_data: @table_data, column_definitions: column_definitions, table_props: { container: false, sticky: true }}) %>
33
+ <%= pb_rails("advanced_table", props: { id: "table_props_table", table_data: @table_data, column_definitions: column_definitions, responsive: "none", table_props: { container: false, sticky: true }}) %>
@@ -1 +1,3 @@
1
- This kit uses the [Table kit](https://playbook.powerapp.cloud/kits/table) under the hood which comes with it's own set of props. If you want to apply certain Table props to that underlying kit, you can do so by using the optional `table_props` prop. This prop must be an object that contains valid Table props. For a full list of Table props, see [here](https://playbook.powerapp.cloud/kits/table).
1
+ This kit uses the [Table kit](https://playbook.powerapp.cloud/kits/table) under the hood which comes with its own set of props. If you want to apply certain Table props to that underlying kit, you can do so by using the optional `table_props` prop. This prop must be an object that contains valid Table props. For a full list of Table props, see [here](https://playbook.powerapp.cloud/kits/table).
2
+
3
+ This doc example showcases how to set a sticky header for a nonresponsive table. To achieve sticky header AND responsive functionality, see the ["Table Props Sticky Header"](https://playbook.powerapp.cloud/kits/advanced_table#table-props-sticky-header) doc example below.
@@ -1,3 +1,3 @@
1
- This kit uses the [Table kit](https://playbook.powerapp.cloud/kits/table/react) under the hood which comes with it's own set of props. If you want to apply certain Table props to that underlying kit, you can do so by using the optional `tableProps` prop. This prop must be an object that contains valid Table props. For a full list of Table props, see [here](https://playbook.powerapp.cloud/kits/table/react).
1
+ This kit uses the [Table kit](https://playbook.powerapp.cloud/kits/table/react) under the hood which comes with its own set of props. If you want to apply certain Table props to that underlying kit, you can do so by using the optional `tableProps` prop. This prop must be an object that contains valid Table props. For a full list of Table props, see [here](https://playbook.powerapp.cloud/kits/table/react).
2
2
 
3
3
  This doc example showcases how to set a sticky header for a nonresponsive table. To achieve sticky header AND responsive functionality, see the ["Table Props Sticky Header"](https://playbook.powerapp.cloud/kits/advanced_table/react#table-props-sticky-header) doc example below.
@@ -0,0 +1,33 @@
1
+ <% column_definitions = [
2
+ {
3
+ accessor: "year",
4
+ label: "Year",
5
+ cellAccessors: ["quarter", "month", "day"],
6
+ },
7
+ {
8
+ accessor: "newEnrollments",
9
+ label: "New Enrollments",
10
+ },
11
+ {
12
+ accessor: "scheduledMeetings",
13
+ label: "Scheduled Meetings",
14
+ },
15
+ {
16
+ accessor: "attendanceRate",
17
+ label: "Attendance Rate",
18
+ },
19
+ {
20
+ accessor: "completedClasses",
21
+ label: "Completed Classes",
22
+ },
23
+ {
24
+ accessor: "classCompletionRate",
25
+ label: "Class Completion Rate",
26
+ },
27
+ {
28
+ accessor: "graduatedStudents",
29
+ label: "Graduated Students",
30
+ }
31
+ ] %>
32
+
33
+ <%= pb_rails("advanced_table", props: { id: "table_props_table", table_data: @table_data, column_definitions: column_definitions, max_height: "xs", table_props: { sticky: true }}) %>
@@ -0,0 +1,3 @@
1
+ Create a sticky header that works for responsive Advanced Tables by setting `sticky: true` via `table_props` and giving the AdvancedTable a `max_height` using our [Max Height](https://playbook.powerapp.cloud/visual_guidelines/max_height) global prop. This behavior requires a `max_height` to work. The header is sticky within the table container, allowing for it to work along with the first column stickiness of a responsive table on smaller screen sizes.
2
+
3
+ A sticky header on a nonresponsive table is demonstrated in the ["Table Props"](https://playbook.powerapp.cloud/kits/advanced_table#table-props) doc example above.
@@ -5,6 +5,7 @@ examples:
5
5
  - advanced_table_beta_subrow_headers: SubRow Headers
6
6
  - advanced_table_collapsible_trail_rails: Collapsible Trail
7
7
  - advanced_table_table_props: Table Props
8
+ - advanced_table_table_props_sticky_header: Table Props Sticky Header
8
9
  - advanced_table_beta_sort: Enable Sorting
9
10
  - advanced_table_responsive: Responsive Tables
10
11
  - advanced_table_custom_cell_rails: Custom Components for Cells
@@ -30,6 +31,7 @@ examples:
30
31
  - advanced_table_pagination_with_props: Pagination Props
31
32
  - advanced_table_column_headers: Multi-Header Columns
32
33
  - advanced_table_column_headers_multiple: Multi-Header Columns (Multiple Levels)
34
+ - advanced_table_column_headers_custom_cell: Multi-Header Columns with Custom Cells
33
35
  # - advanced_table_no_subrows: Table with No Subrows
34
36
  - advanced_table_selectable_rows: Selectable Rows
35
37
  - advanced_table_selectable_rows_no_subrows: Selectable Rows (No Subrows)
@@ -19,4 +19,5 @@ export { default as AdvancedTableSelectableRowsNoSubrows } from './_advanced_tab
19
19
  export { default as AdvancedTableNoSubrows } from './_advanced_table_no_subrows.jsx'
20
20
  export { default as AdvancedTableSelectableRowsHeader } from './_advanced_table_selectable_rows_header.jsx'
21
21
  export { default as AdvancedTableSelectableRowsActions } from './_advanced_table_selectable_rows_actions.jsx'
22
- export { default as AdvancedTableTablePropsStickyHeader } from './_advanced_table_table_props_sticky_header.jsx'
22
+ export { default as AdvancedTableTablePropsStickyHeader } from './_advanced_table_table_props_sticky_header.jsx'
23
+ export { default as AdvancedTableColumnHeadersCustomCell } from './_advanced_table_column_headers_custom_cell.jsx'
@@ -1,4 +1,4 @@
1
- import React, { useEffect, useRef } from 'react'
1
+ import React, { useEffect, useRef, forwardRef } from 'react'
2
2
  import Body from '../pb_body/_body'
3
3
  import Icon from '../pb_icon/_icon'
4
4
  import { buildAriaProps, buildCss, buildDataProps, buildHtmlProps } from '../utilities/props'
@@ -24,7 +24,7 @@ type CheckboxProps = {
24
24
  value?: string,
25
25
  } & GlobalProps
26
26
 
27
- const Checkbox = (props: CheckboxProps): React.ReactElement => {
27
+ const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>((props, ref) => {
28
28
  const {
29
29
  aria = {},
30
30
  checked = false,
@@ -44,7 +44,15 @@ const Checkbox = (props: CheckboxProps): React.ReactElement => {
44
44
  value = '',
45
45
  } = props
46
46
 
47
- const checkRef = useRef(null)
47
+ const internalRef = useRef<HTMLInputElement>(null)
48
+ const setRefs = (el: HTMLInputElement) => {
49
+ internalRef.current = el
50
+ if (typeof ref === 'function') {
51
+ ref(el)
52
+ } else if (ref) {
53
+ (ref as React.MutableRefObject<HTMLInputElement | null>).current = el
54
+ }
55
+ }
48
56
  const ariaProps = buildAriaProps(aria)
49
57
  const dataProps = buildDataProps(data)
50
58
  const htmlProps = buildHtmlProps(htmlOptions)
@@ -56,9 +64,9 @@ const Checkbox = (props: CheckboxProps): React.ReactElement => {
56
64
  )
57
65
 
58
66
  useEffect(() => {
59
- if (checkRef.current) {
60
- checkRef.current.checked = checked
61
- checkRef.current.indeterminate = indeterminate
67
+ if (internalRef.current) {
68
+ internalRef.current.checked = checked
69
+ internalRef.current.indeterminate = indeterminate
62
70
  }
63
71
  }, [indeterminate, checked])
64
72
 
@@ -72,7 +80,7 @@ const Checkbox = (props: CheckboxProps): React.ReactElement => {
72
80
  disabled={disabled}
73
81
  name={name}
74
82
  onChange={onChange}
75
- ref={checkRef}
83
+ ref={setRefs}
76
84
  tabIndex={tabIndex}
77
85
  type="checkbox"
78
86
  value={value}
@@ -119,6 +127,7 @@ const Checkbox = (props: CheckboxProps): React.ReactElement => {
119
127
  </Body>
120
128
  </label>
121
129
  )
122
- }
130
+ })
123
131
 
132
+ Checkbox.displayName = "Checkbox"
124
133
  export default Checkbox
@@ -106,3 +106,19 @@ test('has disabled attribute', () => {
106
106
  const input = kit.querySelector('input')
107
107
  expect(input).toHaveAttribute('disabled')
108
108
  })
109
+
110
+ test('has ref in the input element', () => {
111
+ const ref = React.createRef()
112
+ render(
113
+ <Checkbox
114
+ data={{ testid: testId }}
115
+ name="checkbox-name"
116
+ ref={ref}
117
+ text="Checkbox"
118
+ value="check-box value"
119
+ />
120
+ )
121
+
122
+ expect(ref.current).not.toBeNull()
123
+ expect(ref.current?.tagName).toBe('INPUT')
124
+ })
@@ -0,0 +1,69 @@
1
+ import React, { useState } from "react"
2
+ import { useForm } from "react-hook-form"
3
+ import { Button, Checkbox, Flex, Body } from "playbook-ui"
4
+
5
+ const CheckboxReactHook = () => {
6
+ const { register, handleSubmit } = useForm({
7
+ defaultValues: {
8
+ Small: false,
9
+ Medium: false,
10
+ Large: false,
11
+ },
12
+ })
13
+
14
+ const [submittedData, setSubmittedData] = useState({
15
+ Small: false,
16
+ Medium: false,
17
+ Large: false,
18
+ })
19
+
20
+ const onSubmit = (data) => {
21
+ setSubmittedData(data)
22
+ }
23
+
24
+ return (
25
+ <Flex orientation="row">
26
+ <Flex align="start"
27
+ orientation="column"
28
+ paddingRight="lg"
29
+ >
30
+ <form onSubmit={handleSubmit(onSubmit)}>
31
+ <Checkbox padding="xs"
32
+ text="Small"
33
+ {...register("Small")}
34
+ />
35
+ <br />
36
+ <Checkbox padding="xs"
37
+ text="Medium"
38
+ {...register("Medium")}
39
+ />
40
+ <br />
41
+ <Checkbox padding="xs"
42
+ text="Large"
43
+ {...register("Large")}
44
+ />
45
+ <br />
46
+ <Button htmlType="submit"
47
+ marginTop="sm"
48
+ text="submit"
49
+ />
50
+ </form>
51
+ </Flex>
52
+ <Flex align="start"
53
+ orientation="column"
54
+ >
55
+ <Body padding="xs"
56
+ text={`Small: ${submittedData.Small ? "true" : "false"}`}
57
+ />
58
+ <Body padding="xs"
59
+ text={`Medium: ${submittedData.Medium ? "true" : "false"}`}
60
+ />
61
+ <Body padding="xs"
62
+ text={`Large: ${submittedData.Large ? "true" : "false"}`}
63
+ />
64
+ </Flex>
65
+ </Flex>
66
+ )
67
+ }
68
+
69
+ export default CheckboxReactHook
@@ -0,0 +1 @@
1
+ You can pass react hook props to the checkbox kit.
@@ -11,6 +11,7 @@ examples:
11
11
  react:
12
12
  - checkbox_default: Default
13
13
  - checkbox_checked: Load as checked
14
+ - checkbox_react_hook: React Hook Form
14
15
  - checkbox_custom: Custom Checkbox
15
16
  - checkbox_error: Default w/ Error
16
17
  - checkbox_indeterminate: Indeterminate Checkbox
@@ -21,4 +22,4 @@ examples:
21
22
  - checkbox_error_swift: Default w/ Error
22
23
  - checkbox_indeterminate_swift: Indeterminate Checkbox
23
24
  - checkbox_props_swift: ""
24
-
25
+
@@ -1,5 +1,6 @@
1
1
  export { default as CheckboxDefault } from './_checkbox_default.jsx'
2
2
  export { default as CheckboxCustom } from './_checkbox_custom.jsx'
3
+ export { default as CheckboxReactHook } from './_checkbox_react_hook.jsx'
3
4
  export { default as CheckboxError } from './_checkbox_error.jsx'
4
5
  export { default as CheckboxChecked } from './_checkbox_checked.jsx'
5
6
  export { default as CheckboxIndeterminate } from './_checkbox_indeterminate.jsx'
@@ -8,6 +8,7 @@ import OverlayToken from './subcomponents/_overlay_token'
8
8
  export type OverlayChildrenProps = {
9
9
  children: React.ReactNode[] | React.ReactNode,
10
10
  color: "card_light" | "bg_light" | "card_dark" | "bg_dark",
11
+ dynamic?: boolean,
11
12
  position: string,
12
13
  size: string,
13
14
  }
@@ -18,6 +19,7 @@ type OverlayProps = {
18
19
  children: React.ReactNode[] | React.ReactNode,
19
20
  color: "card_light" | "bg_light" | "card_dark" | "bg_dark",
20
21
  data?: { [key: string]: string },
22
+ dynamic?: false,
21
23
  htmlOptions?: { [key: string]: string | number | boolean | (() => void) },
22
24
  id?: string,
23
25
  layout: { [key: string]: string },
@@ -30,6 +32,7 @@ const Overlay = (props: OverlayProps) => {
30
32
  children,
31
33
  color = "card_light",
32
34
  data = {},
35
+ dynamic = false,
33
36
  htmlOptions = {},
34
37
  id,
35
38
  layout = { "bottom": "full" },
@@ -69,6 +72,7 @@ const Overlay = (props: OverlayProps) => {
69
72
  }) : OverlayToken({
70
73
  children,
71
74
  color,
75
+ dynamic: dynamic,
72
76
  position: getPosition(),
73
77
  size: getSize()
74
78
  })
@@ -0,0 +1,37 @@
1
+ import React, { forwardRef } from 'react'
2
+ import {
3
+ Overlay,
4
+ Card,
5
+ Flex,
6
+ FlexItem,
7
+ } from 'playbook-ui'
8
+
9
+ const InlineCardsExample = forwardRef(function InlineCardsExample(ref) {
10
+ return (
11
+ <Flex
12
+ columnGap="lg"
13
+ orientation="row"
14
+ ref={ref}
15
+ >
16
+ {Array.from({ length: 15 }, (_, index) => (
17
+ <FlexItem key={index}>
18
+ <Card>{"Card Content"}</Card>
19
+ </FlexItem>
20
+ ))}
21
+ </Flex>
22
+ )
23
+ })
24
+
25
+ const OverlayVerticalDynamicMultiDirectional = () => (
26
+ <>
27
+ <Overlay
28
+ color="card_light"
29
+ dynamic
30
+ layout={{"x": "xl"}}
31
+ >
32
+ <InlineCardsExample />
33
+ </Overlay>
34
+ </>
35
+ )
36
+
37
+ export default OverlayVerticalDynamicMultiDirectional
@@ -0,0 +1 @@
1
+ Pass the `dynamic` prop to make the overlay render while the scrollbar isn't at either end on the scrollbar. You must also add a `ref` to the child that's being passed through the Overlay.
@@ -2,6 +2,7 @@ examples:
2
2
  react:
3
3
  - overlay_default: Default
4
4
  - overlay_multi_directional: Multi-directional
5
+ - overlay_vertical_dynamic_multi_directional: Vertical Dynamic Multi-directional
5
6
  - overlay_toggle: Toggle
6
7
 
7
8
  rails:
@@ -1,3 +1,4 @@
1
1
  export { default as OverlayDefault } from './_overlay_default.jsx'
2
2
  export { default as OverlayMultiDirectional } from './_overlay_multi_directional.jsx'
3
3
  export { default as OverlayToggle } from './_overlay_toggle.jsx'
4
+ export { default as OverlayVerticalDynamicMultiDirectional } from './_overlay_vertical_dynamic_multi_directional.jsx'
@@ -1,5 +1,5 @@
1
- import React from 'react'
2
- import { OverlayChildrenProps } from '../_overlay'
1
+ import React, { useRef, useEffect, useState } from 'react';
2
+ import { OverlayChildrenProps } from '../_overlay';
3
3
 
4
4
  const previousOverlayDirectionMap: { [key: string]: string } = {
5
5
  "x": "left",
@@ -15,11 +15,40 @@ const OverlayToken = (props: OverlayChildrenProps) => {
15
15
  const {
16
16
  children,
17
17
  color,
18
+ dynamic,
18
19
  position,
19
20
  size,
20
21
  } = props
21
22
 
22
- const hasSubsequentOverlay = position === "x" || position === "y"
23
+ const scrollContainerRef = useRef<HTMLDivElement>(null);
24
+ const [isAtStart, setIsAtStart] = useState(true);
25
+ const [isAtEnd, setIsAtEnd] = useState(false);
26
+
27
+
28
+ const handleScroll = () => {
29
+ const container = scrollContainerRef.current;
30
+ if (container) {
31
+ const { scrollLeft, scrollWidth, clientWidth } = container;
32
+ const atStart = scrollLeft === 0;
33
+ const atEnd = scrollLeft + clientWidth >= scrollWidth - 1;
34
+
35
+ setIsAtStart(atStart);
36
+ setIsAtEnd(atEnd);
37
+ }
38
+ };
39
+
40
+ useEffect(() => {
41
+ const container = scrollContainerRef.current;
42
+ if (container) {
43
+ container.addEventListener('scroll', handleScroll);
44
+ handleScroll();
45
+ return () => {
46
+ container.removeEventListener('scroll', handleScroll);
47
+ };
48
+ }
49
+ }, []);
50
+
51
+ const hasSubsequentOverlay = position === "x" || position === "y";
23
52
 
24
53
  const getPreviousOverlayDirection = () => {
25
54
  return hasSubsequentOverlay ? previousOverlayDirectionMap[position] : position
@@ -34,15 +63,24 @@ const OverlayToken = (props: OverlayChildrenProps) => {
34
63
 
35
64
  return (
36
65
  <>
37
- <div className={previousOverlayClassName} />
38
-
39
- {children}
40
-
41
- { hasSubsequentOverlay &&
42
- <div className={subsequentOverlayClassName} />
66
+ <div className={dynamic ? isAtStart ? '' : previousOverlayClassName : previousOverlayClassName} />
67
+ {dynamic ?
68
+ <div
69
+ ref={scrollContainerRef}
70
+ style={{
71
+ overflowX: 'auto',
72
+ }}
73
+ >
74
+ {children}
75
+ </div>
76
+ :
77
+ children
78
+ }
79
+ {hasSubsequentOverlay &&
80
+ <div className={dynamic ? isAtEnd ? '' : subsequentOverlayClassName : subsequentOverlayClassName} />
43
81
  }
44
82
  </>
45
83
  )
46
84
  }
47
85
 
48
- export default OverlayToken
86
+ export default OverlayToken;
@@ -1,9 +1,4 @@
1
- <%= content_tag(:div,
2
- aria: object.aria_attributes,
3
- id: object.id,
4
- data: object.data,
5
- class: object.classname,
6
- **combined_html_options) do %>
1
+ <%= pb_content_tag do %>
7
2
 
8
3
  <div class="progress_pills_status">
9
4
  <% object.with_status do |status| %>
@@ -1,11 +1,7 @@
1
1
  <%= content_tag(:div,
2
2
  class: object.wrapper_classname,
3
3
  style: object.style) do %>
4
- <%= content_tag(:div,
5
- id: object.id,
6
- data: object.data_values,
7
- class: object.classname,
8
- **combined_html_options) do %>
4
+ <%= pb_content_tag do %>
9
5
  <%= content_tag(:div, "",
10
6
  class: "progress_simple_value",
11
7
  style: object.value_style) %>
@@ -1,7 +1,3 @@
1
- <%= content_tag(:ul,
2
- id: object.id,
3
- data: object.data,
4
- class: object.classname,
5
- **combined_html_options) do %>
1
+ <%= pb_content_tag(:ul) do %>
6
2
  <%= content.presence %>
7
3
  <% end %>
@@ -1,8 +1,4 @@
1
- <%= content_tag(:li,
2
- id: object.id,
3
- data: object.data,
4
- class: object.classname,
5
- **combined_html_options) do %>
1
+ <%= pb_content_tag(:li) do %>
6
2
  <div class="box" style="max-width: min-content;" id="<%= object.tooltip_trigger_class %>">
7
3
  <div class="circle">
8
4
  <%= pb_rails("icon", props: { icon: object.icon, size: "xs" }) if object.icon.present? %>