playbook_ui 14.18.0.pre.alpha.dropdownautocomplete7493 → 14.18.0.pre.alpha.play1736highchartslinegraphdefaultrebuild7431
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/pb_advanced_table/_advanced_table.scss +21 -304
- data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.tsx +1 -5
- data/app/pb_kits/playbook/pb_advanced_table/advanced_table.rb +1 -6
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_beta.md +6 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/{_advanced_table_selectable_rows_no_subrows_react.jsx → _advanced_table_selectable_rows_no_subrows.jsx} +2 -2
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_selectable_rows_no_subrows_rails.md +1 -5
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_selectable_rows_rails.md +2 -3
- data/app/pb_kits/playbook/pb_advanced_table/docs/example.yml +5 -6
- data/app/pb_kits/playbook/pb_advanced_table/docs/index.js +2 -3
- data/app/pb_kits/playbook/pb_advanced_table/index.js +11 -228
- data/app/pb_kits/playbook/pb_advanced_table/table_body.rb +1 -9
- data/app/pb_kits/playbook/pb_advanced_table/table_header.rb +3 -0
- data/app/pb_kits/playbook/pb_advanced_table/table_row.rb +2 -1
- data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_error.html.erb +2 -2
- data/app/pb_kits/playbook/pb_draggable/docs/example.yml +1 -2
- data/app/pb_kits/playbook/pb_draggable/draggable.rb +1 -9
- data/app/pb_kits/playbook/pb_draggable/index.js +142 -139
- data/app/pb_kits/playbook/pb_dropdown/_dropdown.scss +0 -5
- data/app/pb_kits/playbook/pb_dropdown/_dropdown.tsx +16 -5
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_error.html.erb +2 -5
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_autocomplete.jsx +64 -17
- data/app/pb_kits/playbook/pb_dropdown/docs/{_dropdown_with_autocomplete_with_subcomponents.jsx → _dropdown_with_autocomplete_and_custom_display.jsx} +25 -11
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_autocomplete_and_custom_display.md +1 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_hook.jsx +79 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/example.yml +4 -7
- data/app/pb_kits/playbook/pb_dropdown/docs/index.js +2 -2
- data/app/pb_kits/playbook/pb_dropdown/dropdown.html.erb +2 -2
- data/app/pb_kits/playbook/pb_dropdown/dropdown.rb +0 -4
- data/app/pb_kits/playbook/pb_dropdown/dropdown.test.jsx +1 -45
- data/app/pb_kits/playbook/pb_dropdown/dropdown_container.html.erb +0 -10
- data/app/pb_kits/playbook/pb_dropdown/dropdown_container.rb +0 -3
- data/app/pb_kits/playbook/pb_dropdown/dropdown_trigger.html.erb +2 -12
- data/app/pb_kits/playbook/pb_dropdown/dropdown_trigger.rb +1 -3
- data/app/pb_kits/playbook/pb_dropdown/index.js +0 -57
- data/app/pb_kits/playbook/pb_dropdown/keyboard_accessibility.js +0 -26
- data/app/pb_kits/playbook/pb_dropdown/subcomponents/DropdownContainer.tsx +2 -1
- data/app/pb_kits/playbook/pb_dropdown/subcomponents/DropdownTrigger.tsx +4 -4
- data/app/pb_kits/playbook/pb_filter/docs/example.yml +0 -1
- data/app/pb_kits/playbook/pb_form_group/_error_state_mixin.scss +18 -22
- data/app/pb_kits/playbook/pb_line_graph/docs/_line_graph_pb_styles.jsx +1 -1
- data/app/pb_kits/playbook/pb_line_graph/lineGraphTheme.js +49 -0
- data/app/pb_kits/playbook/pb_phone_number_input/_phone_number_input.scss +0 -13
- data/app/pb_kits/playbook/pb_phone_number_input/_phone_number_input.tsx +1 -3
- data/app/pb_kits/playbook/pb_phone_number_input/docs/example.yml +0 -2
- data/app/pb_kits/playbook/pb_phone_number_input/docs/index.js +0 -1
- data/app/pb_kits/playbook/pb_phone_number_input/phone_number_input.rb +0 -3
- data/app/pb_kits/playbook/pb_phone_number_input/phone_number_input.test.js +0 -19
- data/app/pb_kits/playbook/pb_popover/docs/example.yml +0 -1
- data/app/pb_kits/playbook/pb_popover/index.ts +1 -13
- data/app/pb_kits/playbook/pb_popover/popover.rb +0 -2
- data/app/pb_kits/playbook/pb_select/docs/_select_error.html.erb +1 -1
- data/app/pb_kits/playbook/pb_text_input/docs/_text_input_error.html.erb +1 -1
- data/app/pb_kits/playbook/pb_textarea/docs/_textarea_error.html.erb +1 -5
- data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_error_state.html.erb +1 -8
- data/dist/chunks/{_typeahead-D8CsVBZO.js → _typeahead-0GuhDCLl.js} +2 -2
- data/dist/chunks/_weekday_stacked-DGgA3ilU.js +45 -0
- data/dist/chunks/{lib-BmTAc7Nc.js → lib-C8GLwWXp.js} +1 -1
- data/dist/chunks/{pb_form_validation-BWjy4bFn.js → pb_form_validation-Eul4XODx.js} +1 -1
- data/dist/chunks/vendor.js +1 -1
- data/dist/playbook-doc.js +1 -1
- 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 +16 -38
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_border_color.jsx +0 -80
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_border_color.md +0 -3
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_border_color_rails.html.erb +0 -58
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_border_color_rails.md +0 -3
- data/app/pb_kits/playbook/pb_advanced_table/flat_advanced_table.js +0 -106
- data/app/pb_kits/playbook/pb_draggable/docs/_draggable_drop_zones.html.erb +0 -43
- data/app/pb_kits/playbook/pb_draggable/docs/_draggable_drop_zones_colors.html.erb +0 -55
- data/app/pb_kits/playbook/pb_draggable/docs/_draggable_drop_zones_colors_rails.md +0 -1
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_autocomplete.html.erb +0 -28
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_autocomplete_with_subcomponents.html.erb +0 -58
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_autocomplete_with_subcomponents.md +0 -1
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_external_control.md +0 -1
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_search.jsx +0 -61
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_search.md +0 -2
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_search_rails.html.erb +0 -52
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_search_rails.md +0 -2
- data/app/pb_kits/playbook/pb_filter/docs/_filter_within_turbo_frames.html.erb +0 -41
- data/app/pb_kits/playbook/pb_filter/docs/_filter_within_turbo_frames.md +0 -1
- data/app/pb_kits/playbook/pb_line_graph/docs/_line_graph_pb_styles.md +0 -1
- data/app/pb_kits/playbook/pb_line_graph/lineGraphTheme.ts +0 -110
- data/app/pb_kits/playbook/pb_phone_number_input/docs/_phone_number_input_country_search.html.erb +0 -10
- data/app/pb_kits/playbook/pb_phone_number_input/docs/_phone_number_input_country_search.jsx +0 -20
- data/app/pb_kits/playbook/pb_phone_number_input/docs/_phone_number_input_country_search.md +0 -1
- data/app/pb_kits/playbook/pb_popover/docs/_popover_append_to.html.erb +0 -46
- data/app/pb_kits/playbook/pb_popover/docs/_popover_append_to.md +0 -1
- data/dist/chunks/_weekday_stacked-Da8b-KUp.js +0 -45
- /data/app/pb_kits/playbook/pb_advanced_table/docs/{_advanced_table_selectable_rows_rails.html.erb → _advanced_table_selectable_rows.html.erb} +0 -0
- /data/app/pb_kits/playbook/pb_advanced_table/docs/{_advanced_table_selectable_rows_no_subrows_rails.html.erb → _advanced_table_selectable_rows_no_subrows.html.erb} +0 -0
- /data/app/pb_kits/playbook/pb_advanced_table/docs/{_advanced_table_selectable_rows.md → _advanced_table_selectable_rows_react.md} +0 -0
- /data/app/pb_kits/playbook/pb_draggable/docs/{_draggable_drop_zones_react.md → _draggable_drop_zones.md} +0 -0
- /data/app/pb_kits/playbook/pb_draggable/docs/{_draggable_drop_zones_colors_react.md → _draggable_drop_zones_colors.md} +0 -0
@@ -1,26 +1,24 @@
|
|
1
1
|
import PbEnhancedElement from "../pb_enhanced_element";
|
2
2
|
|
3
|
-
const DRAGGABLE_SELECTOR
|
3
|
+
const DRAGGABLE_SELECTOR = "[data-pb-draggable]";
|
4
4
|
const DRAGGABLE_CONTAINER = ".pb_draggable_container";
|
5
|
-
const NEEDS_CLONE = ["shadow", "outline"]; // clone only for these types
|
6
5
|
|
7
6
|
export default class PbDraggable extends PbEnhancedElement {
|
8
|
-
static get selector() {
|
7
|
+
static get selector() {
|
8
|
+
return DRAGGABLE_SELECTOR;
|
9
|
+
}
|
9
10
|
|
10
11
|
connect() {
|
11
12
|
this.state = {
|
12
|
-
items:
|
13
|
-
dragData:
|
14
|
-
isDragging:
|
15
|
-
activeContainer: ""
|
13
|
+
items: [],
|
14
|
+
dragData: { id: "", initialGroup: "" },
|
15
|
+
isDragging: "",
|
16
|
+
activeContainer: ""
|
16
17
|
};
|
17
18
|
|
18
|
-
this.draggedItem
|
19
|
+
this.draggedItem = null;
|
19
20
|
this.draggedItemId = null;
|
20
|
-
this.dragGhost = null;
|
21
21
|
this.hasMultipleContainers = false;
|
22
|
-
this.dragZoneType = "";
|
23
|
-
this.dragZoneColor = "";
|
24
22
|
|
25
23
|
document.addEventListener("DOMContentLoaded", () => this.bindEventListeners());
|
26
24
|
}
|
@@ -28,12 +26,13 @@ export default class PbDraggable extends PbEnhancedElement {
|
|
28
26
|
setState(newState) {
|
29
27
|
this.state = { ...this.state, ...newState };
|
30
28
|
if (newState.items) {
|
31
|
-
|
29
|
+
const customEvent = new CustomEvent('pb-draggable-reorder', {
|
32
30
|
detail: {
|
33
31
|
reorderedItems: this.state.items,
|
34
|
-
containerId:
|
35
|
-
}
|
36
|
-
})
|
32
|
+
containerId: this.element.querySelector(DRAGGABLE_CONTAINER).id
|
33
|
+
}
|
34
|
+
});
|
35
|
+
this.element.dispatchEvent(customEvent);
|
37
36
|
}
|
38
37
|
}
|
39
38
|
|
@@ -44,100 +43,71 @@ export default class PbDraggable extends PbEnhancedElement {
|
|
44
43
|
|
45
44
|
// Needed to prevent images within draggable items from being independently draggable
|
46
45
|
// Needed if using Image kit in draggable items
|
47
|
-
this.element.querySelectorAll(".pb_draggable_item img")
|
48
|
-
|
49
|
-
|
50
|
-
this.element.querySelectorAll(".pb_draggable_item")
|
51
|
-
.forEach(item => {
|
52
|
-
item.addEventListener("dragstart", this.handleDragStart.bind(this));
|
53
|
-
item.addEventListener("dragend", this.handleDragEnd.bind(this));
|
54
|
-
item.addEventListener("dragenter", this.handleDragEnter.bind(this));
|
55
|
-
});
|
46
|
+
this.element.querySelectorAll(".pb_draggable_item img").forEach(img => {
|
47
|
+
img.setAttribute("draggable", "false");
|
48
|
+
});
|
56
49
|
|
57
|
-
|
58
|
-
|
59
|
-
|
50
|
+
this.element.querySelectorAll(".pb_draggable_item").forEach(item => {
|
51
|
+
item.addEventListener("dragstart", this.handleDragStart.bind(this));
|
52
|
+
item.addEventListener("dragend", this.handleDragEnd.bind(this));
|
53
|
+
item.addEventListener("dragenter", this.handleDragEnter.bind(this));
|
54
|
+
});
|
55
|
+
|
56
|
+
containers.forEach(container => {
|
57
|
+
container.addEventListener("dragover", this.handleDragOver.bind(this));
|
58
|
+
container.addEventListener("drop", this.handleDrop.bind(this));
|
60
59
|
});
|
61
60
|
}
|
62
61
|
|
63
|
-
/* ---------------- DRAG START ---------------- */
|
64
62
|
handleDragStart(event) {
|
65
63
|
// Needed to prevent images within draggable items from being independently draggable
|
66
64
|
// Needed if using Image kit in draggable items
|
67
|
-
if (event.target.tagName.toLowerCase() ===
|
65
|
+
if (event.target.tagName.toLowerCase() === 'img') {
|
68
66
|
event.preventDefault();
|
69
67
|
return;
|
70
68
|
}
|
71
69
|
|
72
|
-
const container
|
73
|
-
this.draggedItem
|
70
|
+
const container = event.target.closest(DRAGGABLE_CONTAINER);
|
71
|
+
this.draggedItem = event.target;
|
74
72
|
this.draggedItemId = event.target.id;
|
75
|
-
this.dragZoneType = this.element.dataset.dropZoneType || "";
|
76
|
-
this.dragZoneColor = this.element.dataset.dropZoneColor || "";
|
77
73
|
|
78
74
|
this.setState({
|
79
|
-
dragData:
|
80
|
-
isDragging: this.draggedItemId
|
75
|
+
dragData: { id: this.draggedItemId, initialGroup: container.id },
|
76
|
+
isDragging: this.draggedItemId
|
81
77
|
});
|
82
78
|
|
83
|
-
|
84
|
-
"is_dragging",
|
85
|
-
`drop_zone_${this.dragZoneType}`,
|
86
|
-
`drop_zone_color_${this.dragZoneColor}`,
|
87
|
-
);
|
88
|
-
|
79
|
+
event.target.classList.add("is_dragging");
|
89
80
|
if (event.dataTransfer) {
|
90
|
-
event.dataTransfer.effectAllowed =
|
91
|
-
event.dataTransfer.setData(
|
92
|
-
|
93
|
-
/* ---------- custom ghost clone (shadow + outline only) ---------- */
|
94
|
-
if (NEEDS_CLONE.includes(this.dragZoneType)) {
|
95
|
-
const ghost = this.draggedItem.cloneNode(true);
|
96
|
-
ghost.classList.remove(
|
97
|
-
"is_dragging",
|
98
|
-
`drop_zone_${this.dragZoneType}`,
|
99
|
-
`drop_zone_color_${this.dragZoneColor}`,
|
100
|
-
);
|
101
|
-
const { width, height } = this.draggedItem.getBoundingClientRect();
|
102
|
-
Object.assign(ghost.style, {
|
103
|
-
border: "none",
|
104
|
-
width: `${width}px`,
|
105
|
-
height: `${height}px`,
|
106
|
-
position: "absolute",
|
107
|
-
top: "-9999px",
|
108
|
-
left: "-9999px",
|
109
|
-
boxSizing: "border-box",
|
110
|
-
zIndex: "9999",
|
111
|
-
});
|
112
|
-
document.body.appendChild(ghost);
|
113
|
-
this.dragGhost = ghost;
|
114
|
-
event.dataTransfer.setDragImage(ghost, width / 2, height / 2);
|
115
|
-
}
|
116
|
-
/* ---------------------------------------------------------------- */
|
81
|
+
event.dataTransfer.effectAllowed = 'move';
|
82
|
+
event.dataTransfer.setData('text/plain', this.draggedItemId);
|
117
83
|
}
|
118
84
|
|
119
|
-
|
85
|
+
setTimeout(() => {
|
86
|
+
event.target.style.opacity = '0.5';
|
87
|
+
}, 0);
|
120
88
|
}
|
121
89
|
|
122
|
-
/* ---------------- DRAG ENTER ---------------- */
|
123
90
|
handleDragEnter(event) {
|
124
91
|
if (!this.draggedItem || event.target === this.draggedItem) return;
|
125
|
-
|
126
|
-
|
127
|
-
|
92
|
+
|
93
|
+
if (this.hasMultipleContainers) {
|
94
|
+
this.handleMultiContainerDragEnter(event);
|
95
|
+
} else {
|
96
|
+
this.handleSingleContainerDragEnter(event);
|
97
|
+
}
|
128
98
|
}
|
129
99
|
|
130
100
|
handleSingleContainerDragEnter(event) {
|
131
|
-
const targetItem = event.target.closest(
|
132
|
-
// If we're entering a container directly or there's no target item
|
101
|
+
const targetItem = event.target.closest('.pb_draggable_item');
|
133
102
|
if (!targetItem) return;
|
134
103
|
|
135
104
|
const container = targetItem.parentNode;
|
136
|
-
const items
|
137
|
-
const fromIdx = items.indexOf(this.draggedItem);
|
138
|
-
const toIdx = items.indexOf(targetItem);
|
105
|
+
const items = Array.from(container.children);
|
139
106
|
|
140
|
-
|
107
|
+
const draggedIndex = items.indexOf(this.draggedItem);
|
108
|
+
const targetIndex = items.indexOf(targetItem);
|
109
|
+
|
110
|
+
if (draggedIndex > targetIndex) {
|
141
111
|
container.insertBefore(this.draggedItem, targetItem);
|
142
112
|
} else {
|
143
113
|
container.insertBefore(this.draggedItem, targetItem.nextSibling);
|
@@ -146,113 +116,146 @@ export default class PbDraggable extends PbEnhancedElement {
|
|
146
116
|
|
147
117
|
handleMultiContainerDragEnter(event) {
|
148
118
|
const targetContainer = event.target.closest(DRAGGABLE_CONTAINER);
|
149
|
-
const targetItem
|
119
|
+
const targetItem = event.target.closest('.pb_draggable_item');
|
120
|
+
|
150
121
|
if (!targetContainer) return;
|
151
122
|
|
123
|
+
// If we're entering a container directly or there's no target item
|
152
124
|
if (!targetItem) {
|
153
|
-
const
|
154
|
-
|
155
|
-
|
156
|
-
|
125
|
+
const lastItem = targetContainer.querySelector('.pb_draggable_item:last-child');
|
126
|
+
if (lastItem) {
|
127
|
+
targetContainer.insertBefore(this.draggedItem, lastItem.nextSibling);
|
128
|
+
} else {
|
129
|
+
targetContainer.appendChild(this.draggedItem);
|
130
|
+
}
|
157
131
|
return;
|
158
132
|
}
|
159
133
|
|
160
|
-
const
|
161
|
-
|
134
|
+
const container = targetItem.parentNode;
|
135
|
+
const items = Array.from(container.children);
|
136
|
+
|
137
|
+
const newItems = [...items].map(item => ({
|
138
|
+
id: item.id,
|
139
|
+
container: container.id
|
140
|
+
}));
|
141
|
+
|
142
|
+
this.setState({ items: newItems });
|
162
143
|
|
163
|
-
const
|
164
|
-
|
144
|
+
const rect = targetItem.getBoundingClientRect();
|
145
|
+
const middleY = rect.top + rect.height / 2;
|
165
146
|
|
166
|
-
if (event.clientY <
|
167
|
-
|
147
|
+
if (event.clientY < middleY) {
|
148
|
+
container.insertBefore(this.draggedItem, targetItem);
|
168
149
|
} else {
|
169
|
-
|
150
|
+
container.insertBefore(this.draggedItem, targetItem.nextSibling);
|
170
151
|
}
|
171
152
|
}
|
172
153
|
|
173
|
-
/* ---------------- DRAG OVER ---------------- */
|
174
154
|
handleDragOver(event) {
|
175
155
|
event.preventDefault();
|
176
156
|
event.stopPropagation();
|
177
|
-
|
178
|
-
|
179
|
-
|
157
|
+
|
158
|
+
if (this.hasMultipleContainers) {
|
159
|
+
this.handleMultiContainerDragOver(event);
|
160
|
+
} else {
|
161
|
+
this.handleSingleContainerDragOver(event);
|
162
|
+
}
|
180
163
|
}
|
181
164
|
|
182
165
|
handleSingleContainerDragOver(event) {
|
183
166
|
const container = event.target.closest(DRAGGABLE_CONTAINER);
|
184
|
-
if (container)
|
167
|
+
if (container) {
|
168
|
+
container.classList.add("active_container");
|
169
|
+
}
|
185
170
|
}
|
186
171
|
|
187
172
|
handleMultiContainerDragOver(event) {
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
173
|
+
let container;
|
174
|
+
if (event.target.matches(DRAGGABLE_CONTAINER)) {
|
175
|
+
container = event.target;
|
176
|
+
} else {
|
177
|
+
container = event.target.closest(DRAGGABLE_CONTAINER);
|
178
|
+
}
|
179
|
+
|
180
|
+
if (container) {
|
181
|
+
this.setState({ activeContainer: container.id });
|
182
|
+
container.classList.add("active_container");
|
183
|
+
|
184
|
+
// If dragging over empty container or below last item
|
185
|
+
const lastItem = container.querySelector('.pb_draggable_item:last-child');
|
186
|
+
if (!lastItem || (lastItem && event.clientY > lastItem.getBoundingClientRect().bottom)) {
|
187
|
+
if (this.draggedItem && this.draggedItem.parentNode !== container) {
|
188
|
+
container.appendChild(this.draggedItem);
|
189
|
+
}
|
200
190
|
}
|
201
191
|
}
|
202
192
|
}
|
203
193
|
|
204
|
-
/* ---------------- DROP ---------------- */
|
205
194
|
handleDrop(event) {
|
206
195
|
event.preventDefault();
|
207
196
|
event.stopPropagation();
|
208
197
|
|
209
|
-
|
210
|
-
|
211
|
-
|
198
|
+
let container;
|
199
|
+
if (event.target.matches(DRAGGABLE_CONTAINER)) {
|
200
|
+
container = event.target;
|
201
|
+
} else {
|
202
|
+
container = event.target.closest(DRAGGABLE_CONTAINER);
|
203
|
+
}
|
204
|
+
|
212
205
|
if (!container || !this.draggedItem) return;
|
213
206
|
|
214
207
|
container.classList.remove("active_container");
|
215
|
-
this.draggedItem.style.opacity =
|
208
|
+
this.draggedItem.style.opacity = '1';
|
216
209
|
|
217
210
|
// Handle empty containers
|
218
|
-
if (this.hasMultipleContainers && !container.querySelector(
|
211
|
+
if (this.hasMultipleContainers && !container.querySelector('.pb_draggable_item')) {
|
219
212
|
container.appendChild(this.draggedItem);
|
220
213
|
}
|
221
214
|
|
222
215
|
// Updated order of items as an array of item IDs
|
223
|
-
const reorderedItems = Array.from(
|
224
|
-
.
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
detail: { reorderedItems, containerId: container.id },
|
216
|
+
const reorderedItems = Array.from(
|
217
|
+
this.element.querySelectorAll('.pb_draggable_item')
|
218
|
+
).map(item => ({
|
219
|
+
id: item.id,
|
220
|
+
container: item.closest(DRAGGABLE_CONTAINER).id
|
229
221
|
}));
|
230
222
|
|
231
|
-
|
232
|
-
|
223
|
+
// Store reordered items in a data attribute on the container
|
224
|
+
container.setAttribute("data-reordered-items", JSON.stringify(reorderedItems));
|
225
|
+
|
226
|
+
const customEvent = new CustomEvent('pb-draggable-reorder', {
|
227
|
+
detail: {
|
228
|
+
reorderedItems,
|
229
|
+
containerId: container.id,
|
230
|
+
}
|
231
|
+
});
|
232
|
+
|
233
|
+
this.element.dispatchEvent(customEvent);
|
234
|
+
|
235
|
+
this.setState({
|
236
|
+
items: reorderedItems,
|
237
|
+
isDragging: "",
|
238
|
+
activeContainer: ""
|
239
|
+
});
|
240
|
+
|
241
|
+
this.draggedItem = null;
|
233
242
|
this.draggedItemId = null;
|
234
243
|
}
|
235
244
|
|
236
|
-
/* ---------------- DRAG END ---------------- */
|
237
245
|
handleDragEnd(event) {
|
238
|
-
event.target.classList.remove(
|
239
|
-
|
240
|
-
`drop_zone_${this.dragZoneType}`,
|
241
|
-
`drop_zone_color_${this.dragZoneColor}`,
|
242
|
-
);
|
243
|
-
event.target.style.opacity = "1";
|
244
|
-
|
245
|
-
if (this.dragGhost) {
|
246
|
-
document.body.removeChild(this.dragGhost);
|
247
|
-
this.dragGhost = null;
|
248
|
-
}
|
249
|
-
|
250
|
-
this.setState({ isDragging: "", activeContainer: "" });
|
246
|
+
event.target.classList.remove("is_dragging");
|
247
|
+
event.target.style.opacity = '1';
|
251
248
|
|
252
|
-
this.
|
253
|
-
|
249
|
+
this.setState({
|
250
|
+
isDragging: "",
|
251
|
+
activeContainer: ""
|
252
|
+
});
|
254
253
|
|
255
|
-
this.draggedItem
|
254
|
+
this.draggedItem = null;
|
256
255
|
this.draggedItemId = null;
|
256
|
+
|
257
|
+
this.element.querySelectorAll(DRAGGABLE_CONTAINER).forEach(container => {
|
258
|
+
container.classList.remove("active_container");
|
259
|
+
});
|
257
260
|
}
|
258
261
|
}
|
@@ -41,11 +41,6 @@
|
|
41
41
|
outline: unset;
|
42
42
|
transition: box-shadow 0.15s ease-in-out;
|
43
43
|
}
|
44
|
-
&:focus-within {
|
45
|
-
box-shadow: 0px 0px 0 1px $primary !important;
|
46
|
-
outline: unset;
|
47
|
-
transition: box-shadow 0.15s ease-in-out;
|
48
|
-
}
|
49
44
|
|
50
45
|
&[class*="_select_only"] {
|
51
46
|
box-shadow: inset 0 -11px 20px rgba($primary, 0.05);
|
@@ -36,6 +36,7 @@ type DropdownProps = {
|
|
36
36
|
onSelect?: (arg: GenericObject) => null;
|
37
37
|
options: GenericObject;
|
38
38
|
separators?: boolean;
|
39
|
+
triggerRef?: any;
|
39
40
|
variant?: "default" | "subtle";
|
40
41
|
};
|
41
42
|
|
@@ -64,6 +65,7 @@ let Dropdown = (props: DropdownProps, ref: any): React.ReactElement | null => {
|
|
64
65
|
onSelect,
|
65
66
|
options,
|
66
67
|
separators = true,
|
68
|
+
triggerRef,
|
67
69
|
variant = "default",
|
68
70
|
} = props;
|
69
71
|
|
@@ -89,7 +91,7 @@ let Dropdown = (props: DropdownProps, ref: any): React.ReactElement | null => {
|
|
89
91
|
const [focusedOptionIndex, setFocusedOptionIndex] = useState(-1);
|
90
92
|
|
91
93
|
const dropdownRef = useRef(null);
|
92
|
-
const inputRef = useRef
|
94
|
+
const inputRef = useRef(null);
|
93
95
|
const inputWrapperRef = useRef(null);
|
94
96
|
const dropdownContainerRef = useRef(null);
|
95
97
|
|
@@ -97,7 +99,15 @@ let Dropdown = (props: DropdownProps, ref: any): React.ReactElement | null => {
|
|
97
99
|
separateChildComponents(children);
|
98
100
|
|
99
101
|
useEffect(() => {
|
100
|
-
|
102
|
+
// Set the parent element of the trigger to relative to allow for absolute positioning of the dropdown
|
103
|
+
//Only needed for when useDropdown hook used with external trigger
|
104
|
+
if (triggerRef?.current) {
|
105
|
+
const parentElement = triggerRef.current.parentNode;
|
106
|
+
if (parentElement) {
|
107
|
+
parentElement.style.position = 'relative';
|
108
|
+
}
|
109
|
+
}
|
110
|
+
// Handle clicks outside the dropdown
|
101
111
|
const handleClick = handleClickOutside({
|
102
112
|
inputWrapperRef,
|
103
113
|
dropdownContainerRef,
|
@@ -157,7 +167,7 @@ let Dropdown = (props: DropdownProps, ref: any): React.ReactElement | null => {
|
|
157
167
|
};
|
158
168
|
|
159
169
|
const handleWrapperClick = () => {
|
160
|
-
autocomplete && inputRef
|
170
|
+
autocomplete && inputRef.current.focus();
|
161
171
|
toggleDropdown();
|
162
172
|
};
|
163
173
|
|
@@ -192,7 +202,7 @@ let Dropdown = (props: DropdownProps, ref: any): React.ReactElement | null => {
|
|
192
202
|
{...htmlProps}
|
193
203
|
className={classes}
|
194
204
|
id={id}
|
195
|
-
style={{position: "relative"}}
|
205
|
+
style={triggerRef ? { position: "absolute" } : { position: "relative" }}
|
196
206
|
>
|
197
207
|
<DropdownContext.Provider
|
198
208
|
value={{
|
@@ -215,7 +225,8 @@ let Dropdown = (props: DropdownProps, ref: any): React.ReactElement | null => {
|
|
215
225
|
setIsDropDownClosed,
|
216
226
|
setIsInputFocused,
|
217
227
|
setSelected,
|
218
|
-
toggleDropdown
|
228
|
+
toggleDropdown,
|
229
|
+
triggerRef
|
219
230
|
}}
|
220
231
|
>
|
221
232
|
{label &&
|
@@ -1,4 +1,4 @@
|
|
1
|
-
<%
|
1
|
+
<%
|
2
2
|
options = [
|
3
3
|
{ label: 'United States', value: 'United States', id: 'us' },
|
4
4
|
{ label: 'Canada', value: 'Canada', id: 'ca' },
|
@@ -6,7 +6,4 @@
|
|
6
6
|
]
|
7
7
|
%>
|
8
8
|
|
9
|
-
<%= pb_rails("dropdown", props: {
|
10
|
-
error: raw(pb_rails("icon", props: { icon: "warning" }) + " Please make a valid selection"),
|
11
|
-
options: options
|
12
|
-
}) %>
|
9
|
+
<%= pb_rails("dropdown", props: { error: "Please make a valid selection", options: options }) %>
|
@@ -1,39 +1,86 @@
|
|
1
1
|
import React from 'react'
|
2
2
|
|
3
3
|
import Dropdown from '../../pb_dropdown/_dropdown'
|
4
|
+
import Badge from '../../pb_badge/_badge'
|
5
|
+
import FlexItem from '../../pb_flex/_flex_item'
|
6
|
+
import User from '../../pb_user/_user'
|
4
7
|
|
5
8
|
const DropdownWithAutocomplete = (props) => {
|
6
9
|
|
7
10
|
const options = [
|
8
11
|
{
|
9
|
-
label: "
|
10
|
-
value: "
|
11
|
-
|
12
|
-
|
13
|
-
id: "
|
12
|
+
label: "Jasper Furniss",
|
13
|
+
value: "Jasper Furniss",
|
14
|
+
territory: "PHL",
|
15
|
+
title: "Lead UX Engineer",
|
16
|
+
id: "jasper-furniss",
|
17
|
+
status: "Offline"
|
14
18
|
},
|
15
19
|
{
|
16
|
-
label: "
|
17
|
-
value: "
|
18
|
-
|
19
|
-
|
20
|
-
id: "
|
20
|
+
label: "Ramon Ruiz",
|
21
|
+
value: "Ramon Ruiz",
|
22
|
+
territory: "PHL",
|
23
|
+
title: "Senior UX Designer",
|
24
|
+
id: "ramon-ruiz",
|
25
|
+
status: "Away"
|
21
26
|
},
|
22
27
|
{
|
23
|
-
label: "
|
24
|
-
value: "
|
25
|
-
|
26
|
-
|
27
|
-
id: "
|
28
|
+
label: "Carlos Lima",
|
29
|
+
value: "Carlos Lima",
|
30
|
+
territory: "PHL",
|
31
|
+
title: "Nitro Developer",
|
32
|
+
id: "carlos-lima",
|
33
|
+
status: "Online"
|
34
|
+
},
|
35
|
+
{
|
36
|
+
label: "Courtney Long",
|
37
|
+
value: "Courtney Long",
|
38
|
+
territory: "PHL",
|
39
|
+
title: "Lead UX Designer",
|
40
|
+
id: "courtney-long",
|
41
|
+
status: "Online"
|
28
42
|
}
|
29
|
-
]
|
43
|
+
];
|
44
|
+
|
30
45
|
|
31
46
|
return (
|
32
47
|
<div>
|
33
48
|
<Dropdown autocomplete
|
34
49
|
options={options}
|
35
50
|
{...props}
|
36
|
-
|
51
|
+
>
|
52
|
+
{options.map((option) => (
|
53
|
+
<Dropdown.Option key={option.id}
|
54
|
+
option={option}
|
55
|
+
>
|
56
|
+
<>
|
57
|
+
<FlexItem>
|
58
|
+
<User
|
59
|
+
align="left"
|
60
|
+
avatar
|
61
|
+
name={option.label}
|
62
|
+
orientation="horizontal"
|
63
|
+
territory={option.territory}
|
64
|
+
title={option.title}
|
65
|
+
/>
|
66
|
+
</FlexItem>
|
67
|
+
<FlexItem>
|
68
|
+
<Badge
|
69
|
+
rounded
|
70
|
+
text={option.status}
|
71
|
+
variant={`${
|
72
|
+
option.status === "Offline"
|
73
|
+
? "neutral"
|
74
|
+
: option.status === "Online"
|
75
|
+
? "success"
|
76
|
+
: "warning"
|
77
|
+
}`}
|
78
|
+
/>
|
79
|
+
</FlexItem>
|
80
|
+
</>
|
81
|
+
</Dropdown.Option>
|
82
|
+
))}
|
83
|
+
</Dropdown>
|
37
84
|
</div>
|
38
85
|
)
|
39
86
|
}
|
@@ -1,13 +1,15 @@
|
|
1
|
-
import React from 'react'
|
1
|
+
import React, { useState } from 'react'
|
2
2
|
|
3
|
-
import Dropdown from '
|
3
|
+
import Dropdown from '../../pb_dropdown/_dropdown'
|
4
4
|
import Badge from '../../pb_badge/_badge'
|
5
|
-
import Flex from '../../pb_flex/_flex'
|
6
5
|
import FlexItem from '../../pb_flex/_flex_item'
|
6
|
+
import Avatar from '../../pb_avatar/_avatar'
|
7
7
|
import User from '../../pb_user/_user'
|
8
8
|
|
9
9
|
|
10
|
-
const
|
10
|
+
const DropdownWithAutocompleteAndCustomDisplay = (props) => {
|
11
|
+
const [selectedOption, setSelectedOption] = useState();
|
12
|
+
|
11
13
|
const options = [
|
12
14
|
{
|
13
15
|
label: "Jasper Furniss",
|
@@ -43,21 +45,34 @@ const DropdownWithAutocompleteWithSubcomponents = (props) => {
|
|
43
45
|
}
|
44
46
|
];
|
45
47
|
|
48
|
+
const CustomDisplay = () => {
|
49
|
+
return (
|
50
|
+
<>
|
51
|
+
{
|
52
|
+
selectedOption && (
|
53
|
+
<Avatar
|
54
|
+
name={selectedOption.label}
|
55
|
+
size="xs"
|
56
|
+
/>
|
57
|
+
)
|
58
|
+
}
|
59
|
+
</>
|
60
|
+
)
|
61
|
+
};
|
46
62
|
|
47
63
|
return (
|
48
64
|
<div>
|
49
65
|
<Dropdown autocomplete
|
66
|
+
onSelect={(selectedItem) => setSelectedOption(selectedItem)}
|
50
67
|
options={options}
|
51
68
|
{...props}
|
52
69
|
>
|
70
|
+
<Dropdown.Trigger customDisplay={<CustomDisplay/>} />
|
53
71
|
{options.map((option) => (
|
54
72
|
<Dropdown.Option key={option.id}
|
55
73
|
option={option}
|
56
74
|
>
|
57
|
-
|
58
|
-
align="center"
|
59
|
-
justify="between"
|
60
|
-
>
|
75
|
+
<>
|
61
76
|
<FlexItem>
|
62
77
|
<User
|
63
78
|
align="left"
|
@@ -70,7 +85,6 @@ const DropdownWithAutocompleteWithSubcomponents = (props) => {
|
|
70
85
|
</FlexItem>
|
71
86
|
<FlexItem>
|
72
87
|
<Badge
|
73
|
-
dark
|
74
88
|
rounded
|
75
89
|
text={option.status}
|
76
90
|
variant={`${
|
@@ -82,7 +96,7 @@ const DropdownWithAutocompleteWithSubcomponents = (props) => {
|
|
82
96
|
}`}
|
83
97
|
/>
|
84
98
|
</FlexItem>
|
85
|
-
|
99
|
+
</>
|
86
100
|
</Dropdown.Option>
|
87
101
|
))}
|
88
102
|
</Dropdown>
|
@@ -90,4 +104,4 @@ const DropdownWithAutocompleteWithSubcomponents = (props) => {
|
|
90
104
|
)
|
91
105
|
}
|
92
106
|
|
93
|
-
export default
|
107
|
+
export default DropdownWithAutocompleteAndCustomDisplay
|