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.
- checksums.yaml +4 -4
- data/app/pb_kits/playbook/_playbook.scss +1 -0
- data/app/pb_kits/playbook/pb_advanced_table/Components/TableActionBar.tsx +10 -10
- data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.scss +1 -53
- data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.tsx +6 -9
- data/app/pb_kits/playbook/pb_advanced_table/advanced_table.html.erb +1 -1
- data/app/pb_kits/playbook/pb_advanced_table/advanced_table.rb +2 -12
- data/app/pb_kits/playbook/pb_advanced_table/advanced_table_action_bar.js +0 -16
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_selectable_rows_header_rails.html.erb +1 -1
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_selectable_rows_rails.html.erb +1 -1
- data/app/pb_kits/playbook/pb_advanced_table/flat_advanced_table.js +11 -4
- data/app/pb_kits/playbook/pb_advanced_table/index.js +124 -103
- data/app/pb_kits/playbook/pb_advanced_table/scss_partials/advanced_table_sticky_mixin.scss +1 -7
- data/app/pb_kits/playbook/pb_advanced_table/table_body.rb +4 -5
- data/app/pb_kits/playbook/pb_advanced_table/table_header.rb +4 -10
- data/app/pb_kits/playbook/pb_advanced_table/table_row.rb +4 -21
- data/app/pb_kits/playbook/pb_checkbox/index.js +30 -220
- data/app/pb_kits/playbook/pb_pagination/_pagination.tsx +0 -4
- data/app/pb_kits/playbook/pb_pagination/docs/_pagination_default_rails.md +1 -3
- data/app/pb_kits/playbook/pb_pagination/docs/_pagination_default_react.md +1 -3
- data/app/pb_kits/playbook/pb_select/select.rb +2 -4
- data/app/pb_kits/playbook/pb_walkthrough/_walkthrough.scss +0 -0
- data/app/pb_kits/playbook/pb_walkthrough/_walkthrough.tsx +202 -0
- data/app/pb_kits/playbook/pb_walkthrough/docs/_walkthrough_continuous.jsx +69 -0
- data/app/pb_kits/playbook/pb_walkthrough/docs/_walkthrough_default.jsx +71 -0
- data/app/pb_kits/playbook/pb_walkthrough/docs/_walkthrough_multi_beacon.jsx +110 -0
- data/app/pb_kits/playbook/pb_walkthrough/docs/_walkthrough_no_beacon.jsx +76 -0
- data/app/pb_kits/playbook/pb_walkthrough/docs/_walkthrough_no_overlay.jsx +76 -0
- data/app/pb_kits/playbook/pb_walkthrough/docs/_walkthrough_styled.jsx +76 -0
- data/app/pb_kits/playbook/pb_walkthrough/docs/example.yml +10 -0
- data/app/pb_kits/playbook/pb_walkthrough/docs/index.js +6 -0
- data/app/pb_kits/playbook/pb_walkthrough/walkthrough.test.jsx +34 -0
- data/dist/chunks/_weekday_stacked-DVbweLBJ.js +61 -0
- data/dist/chunks/vendor.js +1 -1
- data/dist/menu.yml +7 -0
- data/dist/playbook-doc.js +2 -2
- data/dist/playbook-rails-react-bindings.js +1 -1
- data/dist/playbook-rails.js +1 -1
- data/dist/playbook.css +1 -1
- data/lib/playbook/version.rb +1 -1
- metadata +14 -3
- 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: "
|
62
|
-
|
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: "
|
75
|
-
|
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: "
|
67
|
-
|
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: "
|
91
|
-
|
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
|
13
|
+
const childCheckboxes = document.querySelectorAll(`[data-pb-checkbox-indeterminate-parent="${this.element.id}"] input[type="checkbox"]`);
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
const
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
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
|
-
//
|
71
|
-
const
|
72
|
-
|
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
|
-
|
98
|
-
|
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
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
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
|
-
|
162
|
-
|
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
|
-
|
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
|
}
|
@@ -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
|
-
|
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
|
File without changes
|
@@ -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
|