playbook_ui 14.23.0.pre.alpha.PLAY2138advtableselectablerowsindeterminatecheckboxes9289 → 14.23.0.pre.alpha.PLAY2146dropdownactivestylesreact9141

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 (42) hide show
  1. checksums.yaml +4 -4
  2. data/app/pb_kits/playbook/_playbook.scss +1 -0
  3. data/app/pb_kits/playbook/pb_advanced_table/Components/TableActionBar.tsx +10 -10
  4. data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.scss +1 -53
  5. data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.tsx +6 -9
  6. data/app/pb_kits/playbook/pb_advanced_table/advanced_table.html.erb +1 -1
  7. data/app/pb_kits/playbook/pb_advanced_table/advanced_table.rb +2 -12
  8. data/app/pb_kits/playbook/pb_advanced_table/advanced_table_action_bar.js +0 -16
  9. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_selectable_rows_header_rails.html.erb +1 -1
  10. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_selectable_rows_rails.html.erb +1 -1
  11. data/app/pb_kits/playbook/pb_advanced_table/flat_advanced_table.js +11 -4
  12. data/app/pb_kits/playbook/pb_advanced_table/index.js +124 -103
  13. data/app/pb_kits/playbook/pb_advanced_table/scss_partials/advanced_table_sticky_mixin.scss +1 -7
  14. data/app/pb_kits/playbook/pb_advanced_table/table_body.rb +4 -5
  15. data/app/pb_kits/playbook/pb_advanced_table/table_header.rb +4 -10
  16. data/app/pb_kits/playbook/pb_advanced_table/table_row.rb +4 -21
  17. data/app/pb_kits/playbook/pb_checkbox/index.js +30 -220
  18. data/app/pb_kits/playbook/pb_pagination/_pagination.tsx +0 -4
  19. data/app/pb_kits/playbook/pb_pagination/docs/_pagination_default_rails.md +1 -3
  20. data/app/pb_kits/playbook/pb_pagination/docs/_pagination_default_react.md +1 -3
  21. data/app/pb_kits/playbook/pb_select/select.rb +2 -4
  22. data/app/pb_kits/playbook/pb_walkthrough/_walkthrough.scss +0 -0
  23. data/app/pb_kits/playbook/pb_walkthrough/_walkthrough.tsx +202 -0
  24. data/app/pb_kits/playbook/pb_walkthrough/docs/_walkthrough_continuous.jsx +69 -0
  25. data/app/pb_kits/playbook/pb_walkthrough/docs/_walkthrough_default.jsx +71 -0
  26. data/app/pb_kits/playbook/pb_walkthrough/docs/_walkthrough_multi_beacon.jsx +110 -0
  27. data/app/pb_kits/playbook/pb_walkthrough/docs/_walkthrough_no_beacon.jsx +76 -0
  28. data/app/pb_kits/playbook/pb_walkthrough/docs/_walkthrough_no_overlay.jsx +76 -0
  29. data/app/pb_kits/playbook/pb_walkthrough/docs/_walkthrough_styled.jsx +76 -0
  30. data/app/pb_kits/playbook/pb_walkthrough/docs/example.yml +10 -0
  31. data/app/pb_kits/playbook/pb_walkthrough/docs/index.js +6 -0
  32. data/app/pb_kits/playbook/pb_walkthrough/walkthrough.test.jsx +34 -0
  33. data/dist/chunks/_weekday_stacked-DVbweLBJ.js +61 -0
  34. data/dist/chunks/vendor.js +1 -1
  35. data/dist/menu.yml +7 -0
  36. data/dist/playbook-doc.js +2 -2
  37. data/dist/playbook-rails-react-bindings.js +1 -1
  38. data/dist/playbook-rails.js +1 -1
  39. data/dist/playbook.css +1 -1
  40. data/lib/playbook/version.rb +1 -1
  41. metadata +14 -3
  42. data/dist/chunks/_weekday_stacked-9aguRqOv.js +0 -37
@@ -3,8 +3,6 @@
3
3
  module Playbook
4
4
  module PbAdvancedTable
5
5
  class TableHeader < Playbook::KitBase
6
- prop :id, type: Playbook::Props::String,
7
- default: ""
8
6
  prop :column_definitions, type: Playbook::Props::Array,
9
7
  default: []
10
8
  prop :enable_toggle_expansion, type: Playbook::Props::Enum,
@@ -58,10 +56,8 @@ module Playbook
58
56
  classname: additional_classes.join(" "),
59
57
  }) do
60
58
  pb_rails("checkbox", props: {
61
- id: "#{id ? "#{id}-" : ''}select-all-rows",
62
- indeterminate_main: true,
63
- indeterminate_main_labels: ["", ""],
64
- name: "#{id ? "#{id}-" : ''}select-all-rows",
59
+ id: "select-all-rows",
60
+ name: "select-all-rows",
65
61
  })
66
62
  end
67
63
  end
@@ -71,10 +67,8 @@ module Playbook
71
67
  def render_select_all_checkbox
72
68
  if selectable_rows
73
69
  pb_rails("checkbox", props: {
74
- id: "#{id ? "#{id}-" : ''}select-all-rows",
75
- indeterminate_main: true,
76
- indeterminate_main_labels: ["", ""],
77
- name: "#{id ? "#{id}-" : ''}select-all-rows",
70
+ id: "select-all-rows",
71
+ name: "select-all-rows",
78
72
  data: {
79
73
  action: "click->pb-advanced-table#toggleAllRowSelection",
80
74
  },
@@ -29,10 +29,6 @@ module Playbook
29
29
  default: "header"
30
30
  prop :row_styling, type: Playbook::Props::Array,
31
31
  default: []
32
- prop :last_row, type: Playbook::Props::Boolean,
33
- default: false
34
- prop :immediate_parent_row_id, type: Playbook::Props::String,
35
- default: ""
36
32
 
37
33
  def data
38
34
  Hash(prop(:data)).merge(table_data_attributes)
@@ -58,14 +54,12 @@ module Playbook
58
54
  # Selectable Rows No Subrows - checkboxes in their own first cell
59
55
  def render_checkbox_cell
60
56
  if selectable_rows
61
- prefix = id ? "#{id}-" : ""
62
57
  pb_rails("table/table_cell", props: {
63
58
  classname: "checkbox-cell",
64
59
  }) do
65
60
  pb_rails("checkbox", props: {
66
- id: "#{prefix}select-row-#{row_id || row.object_id}",
67
- indeterminate_parent: "#{id ? "#{id}-" : ''}select-all-rows",
68
- name: "#{prefix}select-row-#{row_id || row.object_id}",
61
+ id: "select-row-#{row_id || row.object_id}",
62
+ name: "select-row-#{row_id || row.object_id}",
69
63
  data: {
70
64
  row_id: row_id || row.object_id.to_s,
71
65
  flat_advanced_table_select: true,
@@ -78,20 +72,9 @@ module Playbook
78
72
  # Selectable Rows w/ Subrows - checkboxes part of toggleable first cell
79
73
  def render_row_checkbox
80
74
  if selectable_rows
81
- prefix = id ? "#{id}-" : ""
82
- indeterminate_parent =
83
- if depth.zero?
84
- "#{prefix}select-all-rows"
85
- else
86
- "#{prefix}select-row-#{immediate_parent_row_id}"
87
- end
88
-
89
75
  pb_rails("checkbox", props: {
90
- id: "#{prefix}select-row-#{row_id || row.object_id}",
91
- indeterminate_main: !last_row,
92
- indeterminate_main_labels: ["", ""],
93
- indeterminate_parent: indeterminate_parent,
94
- name: "#{prefix}select-row-#{row_id || row.object_id}",
76
+ id: "select-row-#{row_id || row.object_id}",
77
+ name: "select-row-#{row_id || row.object_id}",
95
78
  data: {
96
79
  row_id: row_id || row.object_id.to_s,
97
80
  },
@@ -10,239 +10,49 @@ export default class PbCheckbox extends PbEnhancedElement {
10
10
  connect() {
11
11
  const mainCheckboxWrapper = this.element;
12
12
  const mainCheckbox = mainCheckboxWrapper.querySelector('input')
13
- const directChildCheckboxes = document.querySelectorAll(`[data-pb-checkbox-indeterminate-parent="${this.element.id}"] input[type="checkbox"]`);
13
+ const childCheckboxes = document.querySelectorAll(`[data-pb-checkbox-indeterminate-parent="${this.element.id}"] input[type="checkbox"]`);
14
14
 
15
- // Helper function to get all descendant checkboxes
16
- const getAllDescendantCheckboxes = () => {
17
- const descendants = [];
18
- const queue = [...directChildCheckboxes];
19
-
20
- // Breadth-first search to find all nested descendants
21
- while (queue.length > 0) {
22
- const checkbox = queue.shift();
23
- descendants.push(checkbox);
24
-
25
- // Find children of this checkbox
26
- const checkboxWrapper = checkbox.closest('[data-pb-checkbox-indeterminate-main="true"]');
27
- if (checkboxWrapper) {
28
- const childCheckboxes = document.querySelectorAll(`[data-pb-checkbox-indeterminate-parent="${checkboxWrapper.id}"] input[type="checkbox"]`);
29
- queue.push(...childCheckboxes);
30
- }
31
- }
32
-
33
- // Also include any non-"main" checkboxes that have this as a parent
34
- const nonMainChildCheckboxes = document.querySelectorAll(`[data-pb-checkbox-indeterminate-parent="${this.element.id}"] input[type="checkbox"]`);
35
- nonMainChildCheckboxes.forEach(cb => {
36
- if (!descendants.includes(cb)) {
37
- descendants.push(cb);
38
- }
39
- });
40
-
41
- return descendants;
42
- };
43
-
44
- // Helper function to determine checkbox state
45
- const getCheckboxState = (checkboxes) => {
46
- const checkedCount = checkboxes.filter(cb => cb.checked).length;
47
- const totalCount = checkboxes.length;
48
-
49
- return {
50
- allChecked: checkedCount === totalCount,
51
- noneChecked: checkedCount === 0,
52
- indeterminate: !(checkedCount === totalCount || checkedCount === 0),
53
- checkedCount,
54
- totalCount
55
- };
56
- };
57
-
58
- // Helper function to update checkbox visual state
59
- const updateCheckboxVisualState = (checkbox, isIndeterminate, isChecked) => {
60
- checkbox.indeterminate = isIndeterminate;
61
- checkbox.checked = isChecked;
62
- };
63
-
64
- // Helper function to update checkbox label and icons
65
- const updateCheckboxLabelAndIcons = (wrapper, isIndeterminate, checkedCount) => {
66
- const checkAllLabel = wrapper.dataset.pbCheckboxIndeterminateMainLabelCheck ?? 'Check All';
67
- const uncheckAllLabel = wrapper.dataset.pbCheckboxIndeterminateMainLabelUncheck ?? 'Uncheck All';
15
+ const updateMainCheckbox = () => {
16
+ // Count the number of checked child checkboxes
17
+ const checkedCount = Array.from(childCheckboxes).filter(cb => cb.checked).length;
18
+ // Determine if the main checkbox should be in an indeterminate state
19
+ const indeterminate = checkedCount > 0 && checkedCount < childCheckboxes.length;
20
+
21
+ // Set the main checkbox states
22
+ mainCheckbox.indeterminate = indeterminate;
23
+ mainCheckbox.checked = checkedCount > 0;
24
+
25
+ // Determine the main checkbox label based on the number of checked checkboxes
26
+ const checkAllLabel = mainCheckboxWrapper.dataset.pbCheckboxIndeterminateMainLabelCheck ?? 'Check All'
27
+ const uncheckAllLabel = mainCheckboxWrapper.dataset.pbCheckboxIndeterminateMainLabelUncheck ?? 'Uncheck All'
68
28
  const text = checkedCount === 0 ? checkAllLabel : uncheckAllLabel;
69
29
 
70
- // Update label
71
- const bodyKitElement = wrapper.getElementsByClassName('pb_body_kit')[0];
72
- if (bodyKitElement) {
73
- bodyKitElement.textContent = text;
74
- }
75
-
76
- // Update icons
77
- const iconSpan = wrapper.querySelector('[data-pb-checkbox-icon-span]');
78
- if (iconSpan) {
79
- const iconClassToAdd = isIndeterminate ? 'pb_checkbox_indeterminate' : 'pb_checkbox_checkmark';
80
- const iconClassToRemove = isIndeterminate ? 'pb_checkbox_checkmark' : 'pb_checkbox_indeterminate';
81
- iconSpan.classList.add(iconClassToAdd);
82
- iconSpan.classList.remove(iconClassToRemove);
83
- }
84
-
85
- // Toggle icon visibility
86
- const indeterminateIcon = wrapper.getElementsByClassName("indeterminate_icon")[0];
87
- const checkIcon = wrapper.getElementsByClassName("check_icon")[0];
88
-
89
- if (indeterminateIcon) {
90
- indeterminateIcon.classList.toggle('hidden', !isIndeterminate);
91
- }
92
- if (checkIcon) {
93
- checkIcon.classList.toggle('hidden', isIndeterminate);
94
- }
95
- };
30
+ // Determine the icon class to add and remove based on the number of checked checkboxes
31
+ const iconClassToAdd = checkedCount === 0 ? 'pb_checkbox_checkmark' : 'pb_checkbox_indeterminate';
32
+ const iconClassToRemove = checkedCount === 0 ? 'pb_checkbox_indeterminate' : 'pb_checkbox_checkmark';
96
33
 
97
- // Main function to update this checkbox's state
98
- const updateMainCheckbox = () => {
99
- const allDescendantCheckboxes = getAllDescendantCheckboxes();
100
- const state = getCheckboxState(allDescendantCheckboxes);
34
+ // Update main checkbox label
35
+ mainCheckboxWrapper.getElementsByClassName('pb_body_kit')[0].textContent = text;
101
36
 
102
- updateCheckboxVisualState(mainCheckbox, state.indeterminate, state.allChecked);
103
- updateCheckboxLabelAndIcons(mainCheckboxWrapper, state.indeterminate, state.checkedCount);
104
- };
105
-
106
- // Function to update parent checkboxes recursively
107
- const updateParentCheckboxes = () => {
108
- const parentId = mainCheckboxWrapper.dataset.pbCheckboxIndeterminateParent;
109
- if (parentId) {
110
- const parentCheckbox = document.getElementById(parentId);
111
- if (parentCheckbox) {
112
- const parentWrapper = parentCheckbox.closest('[data-pb-checkbox-indeterminate-main="true"]');
113
- if (parentWrapper) {
114
- const parentInstance = parentWrapper.pbCheckboxInstance;
115
- if (parentInstance && parentInstance.updateMainCheckbox) {
116
- parentInstance.updateMainCheckbox();
117
- parentInstance.updateParentCheckboxes();
118
- }
119
- }
120
- }
121
- }
122
- };
123
-
124
- // Function to update non-main checkboxes when their children change
125
- const setupNonMainCheckboxUpdates = () => {
126
- const allCheckboxesWithChildren = document.querySelectorAll('input[type="checkbox"]');
127
- allCheckboxesWithChildren.forEach(cb => {
128
- const checkboxWrapper = cb.closest('[data-pb-checkbox-indeterminate-main="true"]');
129
- if (checkboxWrapper && checkboxWrapper !== mainCheckboxWrapper) {
130
- return; // Skip different "main" checkboxes
131
- }
132
-
133
- const childCheckboxes = document.querySelectorAll(`[data-pb-checkbox-indeterminate-parent="${cb.id}"] input[type="checkbox"]`);
134
- if (childCheckboxes.length > 0) {
135
- childCheckboxes.forEach(childCb => {
136
- childCb.addEventListener('change', () => {
137
- const state = getCheckboxState(Array.from(childCheckboxes));
138
- updateCheckboxVisualState(cb, state.indeterminate, state.allChecked);
139
-
140
- // Trigger updates on all main checkboxes that might be affected
141
- const mainCheckboxes = document.querySelectorAll('[data-pb-checkbox-indeterminate-main="true"]');
142
- mainCheckboxes.forEach(mainCb => {
143
- const mainInstance = mainCb.pbCheckboxInstance;
144
- if (mainInstance && mainInstance.updateMainCheckbox) {
145
- setTimeout(() => {
146
- mainInstance.updateMainCheckbox();
147
- }, 0);
148
- }
149
- });
150
- });
151
- });
152
- }
153
- });
37
+ // Add and remove the icon class to the main checkbox wrapper
38
+ mainCheckboxWrapper.querySelector('[data-pb-checkbox-icon-span]').classList.add(iconClassToAdd);
39
+ mainCheckboxWrapper.querySelector('[data-pb-checkbox-icon-span]').classList.remove(iconClassToRemove);
40
+
41
+ // Toggle the visibility of the checkbox icon based on the indeterminate state
42
+ mainCheckboxWrapper.getElementsByClassName("indeterminate_icon")[0].classList.toggle('hidden', !indeterminate);
43
+ mainCheckboxWrapper.getElementsByClassName("check_icon")[0].classList.toggle('hidden', indeterminate);
154
44
  };
155
45
 
156
-
157
-
158
- // Initialize checkbox state
46
+ // Set indeterminate icon on main checkbox if initial children checkboxes are checked
159
47
  updateMainCheckbox();
160
48
 
161
- // Handle main checkbox change - propagate to all descendants
162
- mainCheckbox.addEventListener('change', function() {
163
- const allDescendantCheckboxes = getAllDescendantCheckboxes();
164
- const state = getCheckboxState(allDescendantCheckboxes);
165
-
166
- if (state.indeterminate) {
167
- // If indeterminate, uncheck all descendants and the parent
168
- allDescendantCheckboxes.forEach(cb => {
169
- cb.checked = false;
170
- // Dispatch custom event for programmatic changes- change styles in advanced table
171
- cb.dispatchEvent(new Event('checkbox-programmatic-change', { bubbles: true }));
172
- });
173
- this.checked = false;
174
- } else {
175
- // Otherwise, set all descendants to the same state as this checkbox
176
- allDescendantCheckboxes.forEach(cb => {
177
- cb.checked = this.checked;
178
- // Dispatch custom event for programmatic changes- change styles in advanced table
179
- cb.dispatchEvent(new Event('checkbox-programmatic-change', { bubbles: true }));
180
- });
181
- }
182
-
183
- // Update this checkbox first, then parents after a delay
49
+ this.element.querySelector('input').addEventListener('change', function() {
50
+ childCheckboxes.forEach(cb => cb.checked = this.checked);
184
51
  updateMainCheckbox();
185
- setTimeout(() => {
186
- updateParentCheckboxes();
187
- }, 0);
188
-
189
- // Also trigger updates on all main checkboxes to ensure proper state propagation
190
- triggerAllMainCheckboxUpdates();
191
52
  });
192
53
 
193
- // Handle child checkbox changes
194
- directChildCheckboxes.forEach(cb => {
54
+ childCheckboxes.forEach(cb => {
195
55
  cb.addEventListener('change', updateMainCheckbox);
196
56
  });
197
-
198
- // Handle deeper descendant changes
199
- const allDescendantCheckboxes = getAllDescendantCheckboxes();
200
- allDescendantCheckboxes.forEach(cb => {
201
- if (!Array.from(directChildCheckboxes).includes(cb)) {
202
- cb.addEventListener('change', updateMainCheckbox);
203
- }
204
- });
205
-
206
- // Handle non-main child checkboxes
207
- const allChildCheckboxes = document.querySelectorAll(`[data-pb-checkbox-indeterminate-parent="${this.element.id}"] input[type="checkbox"]`);
208
- allChildCheckboxes.forEach(cb => {
209
- if (!allDescendantCheckboxes.includes(cb)) {
210
- cb.addEventListener('change', updateMainCheckbox);
211
- }
212
- });
213
-
214
- // Also trigger updates on all main checkboxes when any checkbox changes
215
- let updateTimeout = null;
216
- const triggerAllMainCheckboxUpdates = () => {
217
- // Debounce the updates to prevent excessive calls
218
- if (updateTimeout) {
219
- clearTimeout(updateTimeout);
220
- }
221
- updateTimeout = setTimeout(() => {
222
- const mainCheckboxes = document.querySelectorAll('[data-pb-checkbox-indeterminate-main="true"]');
223
- mainCheckboxes.forEach(mainCb => {
224
- const mainInstance = mainCb.pbCheckboxInstance;
225
- if (mainInstance && mainInstance.updateMainCheckbox) {
226
- mainInstance.updateMainCheckbox();
227
- }
228
- });
229
- }, 10); // Small delay to batch updates
230
- };
231
-
232
- // Store the original updateMainCheckbox function and create a new one that also triggers updates
233
- const originalUpdateMainCheckbox = updateMainCheckbox;
234
- const enhancedUpdateMainCheckbox = () => {
235
- originalUpdateMainCheckbox();
236
- triggerAllMainCheckboxUpdates();
237
- };
238
-
239
- // Replace the updateMainCheckbox function
240
- mainCheckboxWrapper.pbCheckboxInstance = {
241
- updateMainCheckbox: enhancedUpdateMainCheckbox,
242
- updateParentCheckboxes
243
- };
244
-
245
- // Setup updates for non-main checkboxes with children
246
- setupNonMainCheckboxUpdates();
247
57
  }
248
58
  }
@@ -134,10 +134,6 @@ const Pagination = ( props: PaginationProps) => {
134
134
  className
135
135
  )
136
136
 
137
- if (total <= 1) {
138
- return null;
139
- }
140
-
141
137
  return (
142
138
  <div
143
139
  {...ariaProps}
@@ -3,6 +3,4 @@ Our Pagination kit depends on the <a href="https://github.com/mislav/will_pagina
3
3
 
4
4
  Once you have perfomed the paginated query in your controller file you can use our kit (see code example below) instead of `<%= will_paginate @users %>` in your view file.
5
5
 
6
- You need to add: <code>require "playbook/pagination_renderer"</code> in your apps controller file.
7
-
8
- Note: If the total page count is 0 or 1, the Pagination kit will not be displayed as there aren't multiple pages to navigate.
6
+ You need to add: <code>require "playbook/pagination_renderer"</code> in your apps controller file.
@@ -1,3 +1 @@
1
- The `range` prop determines how many pages to display in the Pagination component. Regardless of this value, the first two and last two pages are always visible to facilitate navigation to the beginning and end of the pagination. If these always-visible pages fall within the specified range, they are included in the display. If they fall outside the range, the pagination will show additional pages up to the number defined by the `range` prop.
2
-
3
- Note: If the `total` pages prop is 0 or 1, the Pagination component will not be displayed, as there aren't multiple pages to navigate.
1
+ The `range` prop determines how many pages to display in the Pagination component. Regardless of this value, the first two and last two pages are always visible to facilitate navigation to the beginning and end of the pagination. If these always-visible pages fall within the specified range, they are included in the display. If they fall outside the range, the pagination will show additional pages up to the number defined by the `range` prop.
@@ -24,9 +24,7 @@ module Playbook
24
24
  prop :validation_message, type: Playbook::Props::String, default: ""
25
25
 
26
26
  def classnames
27
- ([classname] + [inline_class, compact_class, show_arrow_class])
28
- .reject(&:empty?)
29
- .join(" ")
27
+ classname + inline_class + compact_class + show_arrow_class
30
28
  end
31
29
 
32
30
  def all_attributes
@@ -46,7 +44,7 @@ module Playbook
46
44
  end
47
45
 
48
46
  def inline_class
49
- inline ? "inline" : ""
47
+ inline ? " inline " : " "
50
48
  end
51
49
 
52
50
  def compact_class
@@ -0,0 +1,202 @@
1
+ /* eslint-disable react/no-multi-comp */
2
+
3
+ import React from 'react'
4
+ import classnames from 'classnames'
5
+ import { buildAriaProps, buildCss, buildDataProps, buildHtmlProps } from '../utilities/props'
6
+ import { globalProps } from '../utilities/globalProps'
7
+ import Joyride, { TooltipRenderProps } from 'react-joyride'
8
+ import Button from '../pb_button/_button'
9
+ import Flex from '../pb_flex/_flex'
10
+ import SectionSeparator from '../pb_section_separator/_section_separator'
11
+ import Title from '../pb_title/_title'
12
+
13
+ type WalkthroughProps = {
14
+ aria?: { [key: string]: string },
15
+ callback?: () => void,
16
+ className?: string,
17
+ continuous?: boolean,
18
+ data?: { [key: string]: string },
19
+ htmlOptions?: {[key: string]: string | number | boolean | (() => void)},
20
+ id?: string,
21
+ run?: boolean,
22
+ steps?: [],
23
+ stepIndex?: number,
24
+ debug?: boolean,
25
+ disableCloseOnEsc?: boolean,
26
+ disableOverlay?: boolean,
27
+ disableOverlayClose?: boolean,
28
+ disableScrolling?: boolean,
29
+ floaterProps?: Record<string, unknown>,
30
+ hideBackButton?: boolean,
31
+ hideCloseButton?: boolean,
32
+ showProgress?: boolean,
33
+ showSkipButton?: boolean,
34
+ spotlightClicks?: boolean,
35
+ spotlightPadding?: number,
36
+ styles?: {
37
+ options: {
38
+ beaconSize?: number,
39
+ arrowColor?: string,
40
+ backgroundColor?: string,
41
+ primaryColor?: string,
42
+ overlayColor?: string,
43
+ spotlightShadow?: string,
44
+ width?: number,
45
+ zIndex?: number,
46
+ },
47
+ },
48
+ }
49
+
50
+ type TooltipProps = {
51
+ continuous?: boolean,
52
+ className?: string,
53
+ index?: number,
54
+ isLastStep?: boolean,
55
+ size?: number,
56
+ step: {
57
+ title?: string,
58
+ content?: React.ReactNode[] | React.ReactNode | string,
59
+ target: string,
60
+ disableBeacon?: boolean,
61
+ },
62
+ skip?: boolean,
63
+ backProps?: Record<string, unknown>,
64
+ closeProps?: Record<string, unknown>,
65
+ primaryProps?: Record<string, unknown>,
66
+ skipProps?: Record<string, unknown>,
67
+ tooltipProps?: Record<string, unknown>,
68
+ }
69
+
70
+ // eslint-disable-next-line react/display-name
71
+ const Tooltip = React.forwardRef((props: TooltipProps) => (
72
+ <div
73
+ className="pb_card_kit_border_none p_none"
74
+ {...props.tooltipProps}
75
+ >
76
+ {props.step.title && <div>
77
+ <Flex
78
+ align="center"
79
+ justify="between"
80
+ padding="xs"
81
+ >
82
+ <Title
83
+ paddingLeft="xs"
84
+ size={4}
85
+ >
86
+ {props.step.title}
87
+ </Title>
88
+ {props.skip && (
89
+ <Button
90
+ {...props.skipProps}
91
+ id="skip"
92
+ text="Skip Tour"
93
+ variant="link"
94
+ />
95
+ )}
96
+ <Button
97
+ {...props.skipProps}
98
+ id="skip"
99
+ text="Skip Tour"
100
+ variant="link"
101
+ />
102
+ </Flex>
103
+ <SectionSeparator />
104
+ </div>}
105
+
106
+ <Flex padding="sm">{props.step.content}</Flex>
107
+ <SectionSeparator />
108
+ <Flex
109
+ justify={props.index == 0 ? 'end' : 'between'}
110
+ padding="xs"
111
+ >
112
+
113
+ {props.index > 0 && (
114
+ <Button
115
+ {...props.backProps}
116
+ id="back"
117
+ text="Back"
118
+ />
119
+ )}
120
+
121
+ {props.continuous && !props.isLastStep &&
122
+ <Button
123
+ {...props.primaryProps}
124
+ id="next"
125
+ text="Next"
126
+ />
127
+ }
128
+
129
+ {!props.continuous &&
130
+ <Button
131
+ {...props.closeProps}
132
+ id="close"
133
+ text="Close"
134
+ />
135
+ }
136
+
137
+ {!((props.continuous && !props.isLastStep) || (!props.continuous)) &&
138
+ <Button
139
+ {...props.closeProps}
140
+ id="close"
141
+ text="Close"
142
+ />
143
+ }
144
+ </Flex>
145
+ </div>
146
+ )) as unknown as React.ForwardRefRenderFunction<HTMLDivElement, TooltipRenderProps>
147
+
148
+ const Walkthrough = (props: WalkthroughProps): React.ReactElement => {
149
+ const {
150
+ aria = {},
151
+ callback,
152
+ className,
153
+ continuous = false,
154
+ data = {},
155
+ disableOverlay,
156
+ floaterProps = {
157
+ offset: 50,
158
+ },
159
+ htmlOptions = {},
160
+ id,
161
+ run = false,
162
+ steps,
163
+ styles = {
164
+ options: {
165
+ zIndex: 20000,
166
+ },
167
+ },
168
+ showSkipButton,
169
+ } = props
170
+
171
+ const ariaProps = buildAriaProps(aria)
172
+ const dataProps = buildDataProps(data)
173
+ const htmlProps = buildHtmlProps(htmlOptions)
174
+ const classes = classnames(buildCss('pb_walkthrough'), globalProps(props), className)
175
+
176
+ return (
177
+ <div
178
+ {...ariaProps}
179
+ {...dataProps}
180
+ {...htmlProps}
181
+ className={classes}
182
+ id={id}
183
+ >
184
+ <Joyride
185
+ callback={callback}
186
+ continuous={continuous}
187
+ disableOverlay={disableOverlay}
188
+ disableScrolling
189
+ floaterProps={floaterProps}
190
+ run={run}
191
+ showSkipButton={showSkipButton}
192
+ steps={steps}
193
+ styles={styles}
194
+ tooltipComponent={Tooltip}
195
+ {...props}
196
+ />
197
+ </div>
198
+
199
+ )
200
+ }
201
+
202
+ export default Walkthrough
@@ -0,0 +1,69 @@
1
+ import React, { useState } from 'react'
2
+ import Button from '../../pb_button/_button'
3
+ import Walkthrough from '../../pb_walkthrough/_walkthrough'
4
+
5
+ const WalkthroughContinuous = (props) => {
6
+ const [state, setState] = useState({
7
+ run: false,
8
+ steps: [
9
+ {
10
+ title: 'Example Title',
11
+ content: 'Setting the prop - continuous allows the next button to appear and lets the user move to the next step by pressing the next button instead of the beacon',
12
+ target: '.examplePaused',
13
+ },
14
+ {
15
+ title: 'Toggle',
16
+ content: 'Setting the prop - continuous allows the next button to appear and lets the user move to the next step by pressing the next button instead of the beacon',
17
+ target: '.pb_toggle_control',
18
+ },
19
+ {
20
+ title: 'Top Nav',
21
+ content: 'Setting the prop - continuous allows the next button to appear and lets the user move to the next step by pressing the next button instead of the beacon',
22
+ target: '.pb--page--topNav',
23
+ },
24
+ ],
25
+ })
26
+
27
+ return (
28
+ <div>
29
+ <div
30
+ className="examplePaused"
31
+ style={{ 'display': 'inline' }}
32
+ >
33
+ {'Start the Tour. Then click the Beacon to demo the default behavior of the Walkthrough Kit'}
34
+ </div>
35
+ <br />
36
+ <br />
37
+ <Button
38
+ onClick={() => {
39
+ setState({ ...state,
40
+ run: true,
41
+ })
42
+ }}
43
+ >
44
+ {'Start Tour'}
45
+ </Button>
46
+ <br />
47
+ <br />
48
+ <Button
49
+ onClick={() => {
50
+ setState({
51
+ ...state,
52
+ run: false,
53
+ })
54
+ }}
55
+ >
56
+ {'Reset/Stop Tour'}
57
+ </Button>
58
+
59
+ <Walkthrough
60
+ run={state.run}
61
+ steps={state.steps}
62
+ {...props}
63
+ continuous
64
+ />
65
+ </div>
66
+ )
67
+ }
68
+
69
+ export default WalkthroughContinuous