playbook_ui 14.20.0.pre.alpha.PLAY2140upgraderailsdependency8086 → 14.20.0.pre.alpha.PLAY2170checkboxrailsindeterminatelogicinkitPOC7980
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/Components/CustomCell.tsx +1 -1
- data/app/pb_kits/playbook/pb_advanced_table/Components/RegularTableView.tsx +49 -116
- data/app/pb_kits/playbook/pb_advanced_table/Components/TableHeaderCell.tsx +1 -1
- data/app/pb_kits/playbook/pb_advanced_table/Context/AdvancedTableContext.tsx +2 -58
- data/app/pb_kits/playbook/pb_advanced_table/Hooks/useTableActions.ts +1 -1
- data/app/pb_kits/playbook/pb_advanced_table/Hooks/useTableState.ts +4 -16
- data/app/pb_kits/playbook/pb_advanced_table/SubKits/TableHeader.tsx +3 -7
- data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.scss +0 -40
- data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.tsx +3 -13
- data/app/pb_kits/playbook/pb_advanced_table/advanced_table.rb +1 -7
- data/app/pb_kits/playbook/pb_advanced_table/advanced_table.test.jsx +0 -61
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_no_subrows.jsx +1 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/example.yml +2 -6
- data/app/pb_kits/playbook/pb_advanced_table/docs/index.js +1 -3
- data/app/pb_kits/playbook/pb_advanced_table/index.js +0 -2
- data/app/pb_kits/playbook/pb_checkbox/checkbox.html.erb +4 -1
- data/app/pb_kits/playbook/pb_checkbox/checkbox.rb +0 -7
- data/app/pb_kits/playbook/pb_draggable/context/index.tsx +58 -17
- data/app/pb_kits/playbook/pb_dropdown/_dropdown.tsx +3 -12
- data/app/pb_kits/playbook/pb_dropdown/docs/example.yml +0 -2
- data/app/pb_kits/playbook/pb_dropdown/docs/index.js +1 -2
- data/app/pb_kits/playbook/pb_dropdown/index.js +0 -24
- data/app/pb_kits/playbook/pb_dropdown/subcomponents/DropdownOption.tsx +10 -14
- data/app/pb_kits/playbook/pb_dropdown/subcomponents/DropdownTrigger.tsx +15 -26
- data/app/pb_kits/playbook/pb_popover/index.ts +4 -9
- data/app/pb_kits/playbook/pb_table/docs/_table_with_selectable_rows.html.erb +51 -3
- data/app/pb_kits/playbook/pb_table/styles/_mobile_collapse.scss +1 -1
- data/dist/chunks/{_typeahead-CoOpeYom.js → _typeahead-CRW6dJbW.js} +1 -1
- data/dist/chunks/_weekday_stacked-C4d17aYW.js +45 -0
- data/dist/chunks/{lib-D7Va7yqa.js → lib-D5R1BjUn.js} +1 -1
- data/dist/chunks/{pb_form_validation-DSkdRDMf.js → pb_form_validation-BZ2AVAi_.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 +6 -14
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_no_subrows.html.erb +0 -33
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_pinned_rows.jsx +0 -57
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_pinned_rows_react.md +0 -5
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_scrollbar_none.html.erb +0 -33
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_scrollbar_none.jsx +0 -53
- data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_quick_pick_date_display.html.erb +0 -13
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_close_on_select.jsx +0 -42
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_close_on_select.md +0 -1
- data/dist/chunks/_weekday_stacked-B_jpa2Rz.js +0 -45
@@ -3,12 +3,6 @@ import { render, screen, waitFor } from "../utilities/test-utils"
|
|
3
3
|
|
4
4
|
import { AdvancedTable, Pill } from "playbook-ui"
|
5
5
|
|
6
|
-
global.ResizeObserver = class {
|
7
|
-
observe() {}
|
8
|
-
unobserve() {}
|
9
|
-
disconnect() {}
|
10
|
-
};
|
11
|
-
|
12
6
|
const MOCK_DATA = [
|
13
7
|
{
|
14
8
|
year: "2021",
|
@@ -78,36 +72,6 @@ const MOCK_DATA_LOADING = [
|
|
78
72
|
},
|
79
73
|
]
|
80
74
|
|
81
|
-
const MOCK_DATA_WITH_ID = [
|
82
|
-
{
|
83
|
-
id: "1",
|
84
|
-
year: "2021",
|
85
|
-
quarter: null,
|
86
|
-
month: null,
|
87
|
-
day: null,
|
88
|
-
newEnrollments: "20",
|
89
|
-
scheduledMeetings: "10",
|
90
|
-
},
|
91
|
-
{
|
92
|
-
id: "2",
|
93
|
-
year: "2022",
|
94
|
-
quarter: null,
|
95
|
-
month: null,
|
96
|
-
day: null,
|
97
|
-
newEnrollments: "25",
|
98
|
-
scheduledMeetings: "15",
|
99
|
-
},
|
100
|
-
{
|
101
|
-
id: "3",
|
102
|
-
year: "2023",
|
103
|
-
quarter: null,
|
104
|
-
month: null,
|
105
|
-
day: null,
|
106
|
-
newEnrollments: "30",
|
107
|
-
scheduledMeetings: "20",
|
108
|
-
},
|
109
|
-
]
|
110
|
-
|
111
75
|
const columnDefinitions = [
|
112
76
|
{
|
113
77
|
accessor: "year",
|
@@ -548,28 +512,3 @@ test("allowFullScreen prop adds fullscreen class", () => {
|
|
548
512
|
const tableContainer = screen.getByRole("table").closest("div")
|
549
513
|
expect(tableContainer).toHaveClass("advanced-table-allow-fullscreen")
|
550
514
|
})
|
551
|
-
|
552
|
-
test("pinnedRows prop renders pinned rows at top", () => {
|
553
|
-
const pinnedRowsControl = {
|
554
|
-
value: { top: ["1", "3"] },
|
555
|
-
onChange: jest.fn()
|
556
|
-
}
|
557
|
-
|
558
|
-
render(
|
559
|
-
<AdvancedTable
|
560
|
-
columnDefinitions={columnDefinitions}
|
561
|
-
data={{ testid: testId }}
|
562
|
-
pinnedRows={pinnedRowsControl}
|
563
|
-
tableData={MOCK_DATA_WITH_ID}
|
564
|
-
/>
|
565
|
-
)
|
566
|
-
|
567
|
-
const kit = screen.getByTestId(testId)
|
568
|
-
const pinnedRows = kit.querySelectorAll(".pinned-row")
|
569
|
-
|
570
|
-
expect(pinnedRows).toHaveLength(2)
|
571
|
-
|
572
|
-
const firstPinnedRow = pinnedRows[0]
|
573
|
-
expect(firstPinnedRow).toHaveStyle("position: sticky")
|
574
|
-
expect(firstPinnedRow).toHaveStyle("background-color: white")
|
575
|
-
})
|
@@ -13,12 +13,10 @@ examples:
|
|
13
13
|
- advanced_table_column_headers: Multi-Header Columns
|
14
14
|
- advanced_table_column_headers_multiple: Multi-Header Columns (Multiple Levels)
|
15
15
|
- advanced_table_column_border_color_rails: Column Group Border Color
|
16
|
-
- advanced_table_no_subrows: Table with No Subrows or Expansion
|
17
16
|
- advanced_table_selectable_rows_rails: Selectable Rows
|
18
17
|
- advanced_table_selectable_rows_no_subrows_rails: Selectable Rows (No Subrows)
|
19
18
|
- advanced_table_selectable_rows_actions_rails: Selectable Rows (With Actions)
|
20
19
|
- advanced_table_selectable_rows_header_rails: Selectable Rows (No Actions Bar)
|
21
|
-
- advanced_table_scrollbar_none: Advanced Table Scrollbar None
|
22
20
|
|
23
21
|
react:
|
24
22
|
- advanced_table_default: Default (Required Props)
|
@@ -44,7 +42,7 @@ examples:
|
|
44
42
|
- advanced_table_column_headers_multiple: Multi-Header Columns (Multiple Levels)
|
45
43
|
- advanced_table_column_headers_custom_cell: Multi-Header Columns with Custom Cells
|
46
44
|
- advanced_table_column_border_color: Column Group Border Color
|
47
|
-
- advanced_table_no_subrows: Table with No Subrows
|
45
|
+
# - advanced_table_no_subrows: Table with No Subrows
|
48
46
|
- advanced_table_selectable_rows: Selectable Rows
|
49
47
|
- advanced_table_selectable_rows_no_subrows_react: Selectable Rows (No Subrows)
|
50
48
|
- advanced_table_selectable_rows_actions: Selectable Rows (With Actions)
|
@@ -54,6 +52,4 @@ examples:
|
|
54
52
|
- advanced_table_column_visibility: Column Visibility Control
|
55
53
|
- advanced_table_column_visibility_with_state: Column Visibility Control With State
|
56
54
|
- advanced_table_column_visibility_custom: Column Visibility Control with Custom Dropdown
|
57
|
-
- advanced_table_column_visibility_multi: Column Visibility Control with Multi-Header Columns
|
58
|
-
- advanced_table_pinned_rows: Pinned Rows
|
59
|
-
- advanced_table_scrollbar_none: Advanced Table Scrollbar None
|
55
|
+
- advanced_table_column_visibility_multi: Column Visibility Control with Multi-Header Columns
|
@@ -31,6 +31,4 @@ export { default as AdvancedTableColumnBorderColor} from './_advanced_table_colu
|
|
31
31
|
export { default as AdvancedTableColumnVisibility } from './_advanced_table_column_visibility.jsx'
|
32
32
|
export { default as AdvancedTableColumnVisibilityCustom } from './_advanced_table_column_visibility_custom.jsx'
|
33
33
|
export { default as AdvancedTableColumnVisibilityMulti } from './_advanced_table_column_visibility_multi.jsx'
|
34
|
-
export { default as AdvancedTableColumnVisibilityWithState } from './_advanced_table_column_visibility_with_state.jsx'
|
35
|
-
export { default as AdvancedTablePinnedRows } from './_advanced_table_pinned_rows.jsx'
|
36
|
-
export { default as AdvancedTableScrollbarNone} from './_advanced_table_scrollbar_none.jsx'
|
34
|
+
export { default as AdvancedTableColumnVisibilityWithState } from './_advanced_table_column_visibility_with_state.jsx'
|
@@ -569,8 +569,6 @@ class PbAdvancedTableActionBar {
|
|
569
569
|
actionBar.style.height = 'auto';
|
570
570
|
actionBar.style.overflow = 'visible';
|
571
571
|
actionBar.style.opacity = '1';
|
572
|
-
actionBar.style.transitionProperty = 'all';
|
573
|
-
actionBar.style.transitionTimingFunction = 'ease-in-out';
|
574
572
|
actionBar.classList.remove("p_none");
|
575
573
|
actionBar.classList.add("p_xs", "is-visible", "show-action-card");
|
576
574
|
|
@@ -1,4 +1,7 @@
|
|
1
|
-
<%= pb_content_tag(:label
|
1
|
+
<%= pb_content_tag(:label, data: {
|
2
|
+
pb_checkbox_indeterminate_main: object.indeterminate_main,
|
3
|
+
pb_checkbox_indeterminate_parent: object.indeterminate_parent,
|
4
|
+
}) do %>
|
2
5
|
<%= content.presence || object.input %>
|
3
6
|
<span data-pb-checkbox-icon-span="true" class="pb_checkbox_checkmark">
|
4
7
|
<%= pb_rails("icon", props: { icon: "check", classname: "check_icon", fixed_width: true}) %>
|
@@ -31,13 +31,6 @@ module Playbook
|
|
31
31
|
error ? "negative" : nil
|
32
32
|
end
|
33
33
|
|
34
|
-
def data
|
35
|
-
Hash(prop(:data)).merge(
|
36
|
-
pb_checkbox_indeterminate_main: indeterminate_main,
|
37
|
-
pb_checkbox_indeterminate_parent: indeterminate_parent
|
38
|
-
)
|
39
|
-
end
|
40
|
-
|
41
34
|
private
|
42
35
|
|
43
36
|
def error_class
|
@@ -1,11 +1,11 @@
|
|
1
|
-
import React, { createContext, useReducer, useContext, useEffect, useMemo } from "react";
|
1
|
+
import React, { createContext, useReducer, useContext, useEffect, useMemo, useRef, useState } from "react";
|
2
2
|
import { InitialStateType, ActionType, DraggableProviderType } from "./types";
|
3
3
|
|
4
4
|
const initialState: InitialStateType = {
|
5
5
|
items: [],
|
6
6
|
dragData: { id: "", initialGroup: "" },
|
7
7
|
isDragging: "",
|
8
|
-
activeContainer: ""
|
8
|
+
activeContainer: "",
|
9
9
|
};
|
10
10
|
|
11
11
|
const reducer = (state: InitialStateType, action: ActionType) => {
|
@@ -31,9 +31,23 @@ const reducer = (state: InitialStateType, action: ActionType) => {
|
|
31
31
|
const { dragId, targetId } = action.payload;
|
32
32
|
const newItems = [...state.items];
|
33
33
|
const draggedItem = newItems.find(item => item.id === dragId);
|
34
|
-
const
|
34
|
+
const targetItem = newItems.find(item => item.id === targetId);
|
35
|
+
|
36
|
+
if (!draggedItem || !targetItem || draggedItem.container !== targetItem.container) {
|
37
|
+
return state;
|
38
|
+
}
|
39
|
+
|
40
|
+
if (dragId === targetId) {
|
41
|
+
return state;
|
42
|
+
}
|
43
|
+
|
44
|
+
const draggedIndex = newItems.findIndex(item => item.id === dragId);
|
35
45
|
const targetIndex = newItems.findIndex(item => item.id === targetId);
|
36
46
|
|
47
|
+
if (draggedIndex === -1 || targetIndex === -1) {
|
48
|
+
return state;
|
49
|
+
}
|
50
|
+
|
37
51
|
newItems.splice(draggedIndex, 1);
|
38
52
|
newItems.splice(targetIndex, 0, draggedItem);
|
39
53
|
|
@@ -48,7 +62,11 @@ const reducer = (state: InitialStateType, action: ActionType) => {
|
|
48
62
|
const DragContext = createContext<any>({});
|
49
63
|
|
50
64
|
export const DraggableContext = () => {
|
51
|
-
|
65
|
+
const context = useContext(DragContext);
|
66
|
+
if (context === undefined) {
|
67
|
+
throw new Error('DraggableContext must be used within a DraggableProvider');
|
68
|
+
}
|
69
|
+
return context;
|
52
70
|
};
|
53
71
|
|
54
72
|
export const DraggableProvider = ({
|
@@ -63,7 +81,11 @@ export const DraggableProvider = ({
|
|
63
81
|
dropZone = { type: 'ghost', color: 'neutral', direction: 'vertical' }
|
64
82
|
}: DraggableProviderType) => {
|
65
83
|
const [state, dispatch] = useReducer(reducer, initialState);
|
66
|
-
|
84
|
+
|
85
|
+
// Store initial items in a ref to use if needed (for consistency when needed in future updates)
|
86
|
+
const initialItemsRef = useRef(initialItems);
|
87
|
+
const [isDragging, setIsDragging] = useState(false);
|
88
|
+
|
67
89
|
// Parse dropZone prop - handle both string format (backward compatibility) and object format
|
68
90
|
let dropZoneType = 'ghost';
|
69
91
|
let dropZoneColor = 'neutral';
|
@@ -86,45 +108,64 @@ export const DraggableProvider = ({
|
|
86
108
|
|
87
109
|
useEffect(() => {
|
88
110
|
dispatch({ type: 'SET_ITEMS', payload: initialItems });
|
111
|
+
initialItemsRef.current = initialItems;
|
89
112
|
}, [initialItems]);
|
90
113
|
|
91
114
|
useEffect(() => {
|
92
|
-
onReorder
|
93
|
-
|
115
|
+
if (onReorder) {
|
116
|
+
onReorder(state.items);
|
117
|
+
}
|
118
|
+
}, [state.items, onReorder]);
|
94
119
|
|
95
120
|
const handleDragStart = (id: string, container: string) => {
|
96
|
-
|
121
|
+
setIsDragging(true);
|
122
|
+
dispatch({ type: 'SET_DRAG_DATA', payload: { id, initialGroup: container } });
|
97
123
|
dispatch({ type: 'SET_IS_DRAGGING', payload: id });
|
124
|
+
dispatch({ type: 'SET_ACTIVE_CONTAINER', payload: container });
|
98
125
|
if (onDragStart) onDragStart(id, container);
|
99
126
|
};
|
100
127
|
|
101
128
|
const handleDragEnter = (id: string, container: string) => {
|
102
|
-
if (
|
103
|
-
|
104
|
-
|
129
|
+
if (!isDragging || container !== state.activeContainer) return;
|
130
|
+
|
131
|
+
if (state.dragData.id === id) return;
|
132
|
+
|
133
|
+
const draggedItem = state.items.find(item => item.id === state.dragData.id);
|
134
|
+
const targetItem = state.items.find(item => item.id === id);
|
135
|
+
|
136
|
+
if (!draggedItem || !targetItem || draggedItem.container !== targetItem.container) {
|
137
|
+
return;
|
105
138
|
}
|
139
|
+
|
140
|
+
dispatch({ type: 'REORDER_ITEMS', payload: { dragId: state.dragData.id, targetId: id } });
|
141
|
+
|
106
142
|
if (onDragEnter) onDragEnter(id, container);
|
107
143
|
};
|
108
144
|
|
109
145
|
const handleDragEnd = () => {
|
146
|
+
setIsDragging(false);
|
110
147
|
dispatch({ type: 'SET_IS_DRAGGING', payload: "" });
|
111
148
|
dispatch({ type: 'SET_ACTIVE_CONTAINER', payload: "" });
|
112
149
|
if (onDragEnd) onDragEnd();
|
113
150
|
};
|
114
151
|
|
115
|
-
const changeCategory = (itemId: string, container: string) => {
|
116
|
-
dispatch({ type: 'CHANGE_CATEGORY', payload: { itemId, container } });
|
117
|
-
};
|
118
|
-
|
119
152
|
const handleDrop = (container: string) => {
|
153
|
+
const draggedItem = state.items.find(item => item.id === state.dragData.id);
|
154
|
+
|
155
|
+
if (draggedItem && draggedItem.container !== container) {
|
156
|
+
dispatch({ type: 'CHANGE_CATEGORY', payload: { itemId: state.dragData.id, container } });
|
157
|
+
}
|
158
|
+
|
120
159
|
dispatch({ type: 'SET_IS_DRAGGING', payload: "" });
|
121
160
|
dispatch({ type: 'SET_ACTIVE_CONTAINER', payload: "" });
|
122
|
-
|
161
|
+
|
162
|
+
setIsDragging(false);
|
123
163
|
if (onDrop) onDrop(container);
|
124
164
|
};
|
125
165
|
|
126
166
|
const handleDragOver = (e: Event, container: string) => {
|
127
167
|
e.preventDefault();
|
168
|
+
e.stopPropagation();
|
128
169
|
dispatch({ type: 'SET_ACTIVE_CONTAINER', payload: container });
|
129
170
|
if (onDragOver) onDragOver(e, container);
|
130
171
|
};
|
@@ -144,7 +185,7 @@ export const DraggableProvider = ({
|
|
144
185
|
handleDragEnd,
|
145
186
|
handleDrop,
|
146
187
|
handleDragOver
|
147
|
-
}), [state, dropZoneType, dropZoneColor, dropZoneDirection]);
|
188
|
+
}), [state, dropZoneType, dropZoneColor, dropZoneDirection, handleDragStart, handleDragEnter, handleDragEnd, handleDrop, handleDragOver]);
|
148
189
|
|
149
190
|
return (
|
150
191
|
<DragContext.Provider value={contextValue}>{children}</DragContext.Provider>
|
@@ -25,7 +25,6 @@ type DropdownProps = {
|
|
25
25
|
blankSelection?: string;
|
26
26
|
children?: React.ReactChild[] | React.ReactChild | React.ReactElement[];
|
27
27
|
className?: string;
|
28
|
-
closeOnSelection?: boolean;
|
29
28
|
formPillProps?: GenericObject;
|
30
29
|
dark?: boolean;
|
31
30
|
data?: { [key: string]: string };
|
@@ -56,7 +55,6 @@ let Dropdown = (props: DropdownProps, ref: any): React.ReactElement | null => {
|
|
56
55
|
blankSelection = '',
|
57
56
|
children,
|
58
57
|
className,
|
59
|
-
closeOnSelection = true,
|
60
58
|
dark = false,
|
61
59
|
data = {},
|
62
60
|
defaultValue = {},
|
@@ -154,7 +152,7 @@ let Dropdown = (props: DropdownProps, ref: any): React.ReactElement | null => {
|
|
154
152
|
if (!multiSelect) return optionsWithBlankSelection;
|
155
153
|
return optionsWithBlankSelection.filter((option: GenericObject) => !selectedArray.some((sel) => sel.label === option.label));
|
156
154
|
}, [optionsWithBlankSelection, selectedArray, multiSelect]);
|
157
|
-
|
155
|
+
|
158
156
|
const filteredOptions = useMemo(() => {
|
159
157
|
return availableOptions.filter((opt: GenericObject) =>
|
160
158
|
String(opt.label).toLowerCase().includes(filterItem.toLowerCase())
|
@@ -194,18 +192,12 @@ let Dropdown = (props: DropdownProps, ref: any): React.ReactElement | null => {
|
|
194
192
|
return next;
|
195
193
|
});
|
196
194
|
setFilterItem("");
|
197
|
-
|
198
|
-
if (closeOnSelection) {
|
199
|
-
setIsDropDownClosed(true);
|
200
|
-
}
|
195
|
+
setIsDropDownClosed(true);
|
201
196
|
} else {
|
202
197
|
setSelected(clickedItem);
|
203
198
|
setFilterItem("");
|
199
|
+
setIsDropDownClosed(true);
|
204
200
|
onSelect && onSelect(clickedItem);
|
205
|
-
// Only close dropdown if closeOnSelection is true
|
206
|
-
if (closeOnSelection) {
|
207
|
-
setIsDropDownClosed(true);
|
208
|
-
}
|
209
201
|
}
|
210
202
|
};
|
211
203
|
|
@@ -260,7 +252,6 @@ let Dropdown = (props: DropdownProps, ref: any): React.ReactElement | null => {
|
|
260
252
|
<DropdownContext.Provider
|
261
253
|
value={{
|
262
254
|
autocomplete,
|
263
|
-
closeOnSelection,
|
264
255
|
dropdownContainerRef,
|
265
256
|
filteredOptions,
|
266
257
|
filterItem,
|
@@ -19,5 +19,4 @@ export { default as DropdownMultiSelect } from './_dropdown_multi_select.jsx'
|
|
19
19
|
export { default as DropdownMultiSelectDisplay } from './_dropdown_multi_select_display.jsx'
|
20
20
|
export { default as DropdownMultiSelectWithAutocomplete } from './_dropdown_multi_select_with_autocomplete.jsx'
|
21
21
|
export { default as DropdownMultiSelectWithDefault } from './_dropdown_multi_select_with_default.jsx'
|
22
|
-
export { default as DropdownMultiSelectWithCustomOptions } from './_dropdown_multi_select_with_custom_options.jsx'
|
23
|
-
export { default as DropdownCloseOnSelect } from './_dropdown_close_on_select.jsx'
|
22
|
+
export { default as DropdownMultiSelectWithCustomOptions } from './_dropdown_multi_select_with_custom_options.jsx'
|
@@ -115,7 +115,6 @@ export default class PbDropdown extends PbEnhancedElement {
|
|
115
115
|
|
116
116
|
handleSearch(term = "") {
|
117
117
|
const lcTerm = term.toLowerCase();
|
118
|
-
let hasMatch = false
|
119
118
|
this.element.querySelectorAll(OPTION_SELECTOR).forEach((opt) => {
|
120
119
|
//make it so that if the option is selected, it will not show up in the search results
|
121
120
|
if (this.isMultiSelect && this.selectedOptions.has(opt.dataset.dropdownOptionLabel)) {
|
@@ -129,32 +128,9 @@ export default class PbDropdown extends PbEnhancedElement {
|
|
129
128
|
// hide or show option
|
130
129
|
const match = label.includes(lcTerm);
|
131
130
|
opt.style.display = match ? "" : "none";
|
132
|
-
if (match) hasMatch = true
|
133
131
|
});
|
134
132
|
|
135
133
|
this.adjustDropdownHeight();
|
136
|
-
|
137
|
-
this.removeNoOptionsMessage()
|
138
|
-
if (!hasMatch) {
|
139
|
-
this.showNoOptionsMessage()
|
140
|
-
}
|
141
|
-
}
|
142
|
-
|
143
|
-
showNoOptionsMessage() {
|
144
|
-
if (this.element.querySelector(".dropdown_no_options")) return;
|
145
|
-
|
146
|
-
const noOptionElement = document.createElement("div");
|
147
|
-
noOptionElement.className = "pb_body_kit_light dropdown_no_options pb_item_kit p_xs display_flex justify_content_center";
|
148
|
-
noOptionElement.textContent = "no option";
|
149
|
-
|
150
|
-
this.target.appendChild(noOptionElement);
|
151
|
-
}
|
152
|
-
|
153
|
-
removeNoOptionsMessage() {
|
154
|
-
const existing = this.element.querySelector(".dropdown_no_options");
|
155
|
-
if (existing) {
|
156
|
-
existing.remove();
|
157
|
-
}
|
158
134
|
}
|
159
135
|
|
160
136
|
handleOptionClick(event) {
|
@@ -25,7 +25,7 @@ type DropdownOptionProps = {
|
|
25
25
|
key?: string | number;
|
26
26
|
option?: GenericObject;
|
27
27
|
padding?: string;
|
28
|
-
}
|
28
|
+
} & GlobalProps;
|
29
29
|
|
30
30
|
const DropdownOption = (props: DropdownOptionProps) => {
|
31
31
|
const {
|
@@ -56,17 +56,16 @@ const DropdownOption = (props: DropdownOptionProps) => {
|
|
56
56
|
|
57
57
|
// When multiSelect, then if an option is selected, remove from dropdown
|
58
58
|
const isSelected = Array.isArray(selected)
|
59
|
-
|
60
|
-
|
59
|
+
? selected.some((item) => item.label === option?.label)
|
60
|
+
: (selected as GenericObject)?.label === option?.label;
|
61
61
|
|
62
|
+
|
62
63
|
if (!isItemMatchingFilter(option) || (multiSelect && isSelected)) {
|
63
64
|
return null;
|
64
65
|
}
|
65
|
-
|
66
66
|
const isFocused =
|
67
67
|
focusedOptionIndex >= 0 &&
|
68
68
|
filteredOptions[focusedOptionIndex].label === option?.label;
|
69
|
-
|
70
69
|
const focusedClass = isFocused && "focused";
|
71
70
|
|
72
71
|
const selectedClass = isSelected ? "selected" : "list";
|
@@ -92,10 +91,7 @@ const DropdownOption = (props: DropdownOptionProps) => {
|
|
92
91
|
className={classes}
|
93
92
|
id={id}
|
94
93
|
key={key}
|
95
|
-
onClick={(
|
96
|
-
e.stopPropagation();
|
97
|
-
handleOptionClick(option);
|
98
|
-
}}
|
94
|
+
onClick= {() => handleOptionClick(option)}
|
99
95
|
>
|
100
96
|
<ListItem
|
101
97
|
cursor="pointer"
|
@@ -104,12 +100,12 @@ const DropdownOption = (props: DropdownOptionProps) => {
|
|
104
100
|
key={option?.label}
|
105
101
|
padding="none"
|
106
102
|
>
|
107
|
-
|
103
|
+
{children ?
|
108
104
|
<div className="dropdown_option_wrapper">{children}</div> :
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
105
|
+
<Body dark={dark}
|
106
|
+
text={option?.label}
|
107
|
+
/>
|
108
|
+
}
|
113
109
|
</ListItem>
|
114
110
|
</div>
|
115
111
|
);
|
@@ -44,7 +44,6 @@ const DropdownTrigger = (props: DropdownTriggerProps) => {
|
|
44
44
|
|
45
45
|
const {
|
46
46
|
autocomplete,
|
47
|
-
closeOnSelection,
|
48
47
|
filterItem,
|
49
48
|
handleBackspace,
|
50
49
|
handleChange,
|
@@ -55,7 +54,6 @@ const DropdownTrigger = (props: DropdownTriggerProps) => {
|
|
55
54
|
isInputFocused,
|
56
55
|
multiSelect,
|
57
56
|
selected,
|
58
|
-
setIsDropDownClosed,
|
59
57
|
setIsInputFocused,
|
60
58
|
toggleDropdown,
|
61
59
|
} = useContext(DropdownContext);
|
@@ -105,26 +103,11 @@ const DropdownTrigger = (props: DropdownTriggerProps) => {
|
|
105
103
|
? placeholder
|
106
104
|
: "Select...";
|
107
105
|
|
108
|
-
// Click handler that respects closeOnSelection
|
109
|
-
const handleInputClick = (e: React.MouseEvent) => {
|
110
|
-
e.stopPropagation(); // keep the wrapper's handler from firing
|
111
|
-
if (isDropDownClosed) {
|
112
|
-
// Always open if closed
|
113
|
-
setIsDropDownClosed(false);
|
114
|
-
} else if (!closeOnSelection) {
|
115
|
-
// Keep open if closeOnSelection is false
|
116
|
-
return;
|
117
|
-
} else {
|
118
|
-
// Default behavior - toggle
|
119
|
-
toggleDropdown();
|
120
|
-
}
|
121
|
-
};
|
122
|
-
|
123
106
|
return (
|
124
|
-
<div {...ariaProps}
|
125
|
-
{...dataProps}
|
107
|
+
<div {...ariaProps}
|
108
|
+
{...dataProps}
|
126
109
|
{...htmlProps}
|
127
|
-
className={classes}
|
110
|
+
className={classes}
|
128
111
|
id={id}
|
129
112
|
>
|
130
113
|
{
|
@@ -162,7 +145,7 @@ const DropdownTrigger = (props: DropdownTriggerProps) => {
|
|
162
145
|
{customDisplay ? (
|
163
146
|
<Flex align="center">
|
164
147
|
{customDisplay}
|
165
|
-
<Body dark={dark}
|
148
|
+
<Body dark={dark}
|
166
149
|
paddingLeft={`${joinedLabels ? "xs" : "none"}`}
|
167
150
|
>
|
168
151
|
{customDisplayPlaceholder}
|
@@ -181,7 +164,10 @@ const DropdownTrigger = (props: DropdownTriggerProps) => {
|
|
181
164
|
<input
|
182
165
|
className="dropdown_input"
|
183
166
|
onChange={handleChange}
|
184
|
-
onClick={
|
167
|
+
onClick={(e) => {
|
168
|
+
e.stopPropagation();// keep the wrapper’s handler from firing
|
169
|
+
toggleDropdown();
|
170
|
+
}}
|
185
171
|
onFocus={() => setIsInputFocused(true)}
|
186
172
|
onKeyDown={(e) => {
|
187
173
|
handleKeyDown(e);
|
@@ -200,8 +186,8 @@ const DropdownTrigger = (props: DropdownTriggerProps) => {
|
|
200
186
|
)}
|
201
187
|
</>
|
202
188
|
) : (
|
203
|
-
<Body dark={dark}
|
204
|
-
text={defaultDisplayPlaceholder}
|
189
|
+
<Body dark={dark}
|
190
|
+
text={defaultDisplayPlaceholder}
|
205
191
|
/>
|
206
192
|
)
|
207
193
|
)}
|
@@ -209,7 +195,10 @@ const DropdownTrigger = (props: DropdownTriggerProps) => {
|
|
209
195
|
<input
|
210
196
|
className="dropdown_input"
|
211
197
|
onChange={handleChange}
|
212
|
-
onClick={
|
198
|
+
onClick={(e) => {
|
199
|
+
e.stopPropagation();// keep the wrapper’s handler from firing
|
200
|
+
toggleDropdown();
|
201
|
+
}}
|
213
202
|
onFocus={() => setIsInputFocused(true)}
|
214
203
|
onKeyDown={handleKeyDown}
|
215
204
|
placeholder={
|
@@ -234,7 +223,7 @@ const DropdownTrigger = (props: DropdownTriggerProps) => {
|
|
234
223
|
onClick: (e: Event) => {e.stopPropagation();handleWrapperClick()}
|
235
224
|
}}
|
236
225
|
key={`${isDropDownClosed ? "chevron-down" : "chevron-up"}`}
|
237
|
-
>
|
226
|
+
>
|
238
227
|
{
|
239
228
|
selectedArray.length > 0 && (
|
240
229
|
<div onClick={(e)=>{e.stopPropagation();handleBackspace()}}>
|
@@ -13,24 +13,19 @@ export default class PbPopover extends PbEnhancedElement {
|
|
13
13
|
}
|
14
14
|
|
15
15
|
moveTooltip() {
|
16
|
-
let container: HTMLElement | null
|
16
|
+
let container: HTMLElement | null;
|
17
17
|
|
18
18
|
if (this.appendTo === "parent") {
|
19
|
-
container = this.element.parentElement
|
19
|
+
container = this.element.parentElement;
|
20
20
|
} else if (this.appendTo) {
|
21
|
-
container = document.querySelector(this.appendTo)
|
21
|
+
container = document.querySelector(this.appendTo);
|
22
22
|
}
|
23
23
|
|
24
|
-
container.appendChild(this.tooltip);
|
24
|
+
(container || document.body).appendChild(this.tooltip);
|
25
25
|
}
|
26
26
|
|
27
27
|
connect() {
|
28
|
-
if (!this.triggerElement || !this.tooltip) {
|
29
|
-
console.warn('Popover requires both trigger and tooltip elements to be defined.')
|
30
|
-
return
|
31
|
-
}
|
32
28
|
this.moveTooltip()
|
33
|
-
|
34
29
|
this.popper = createPopper (this.triggerElement, this.tooltip, {
|
35
30
|
placement: this.position as Placement,
|
36
31
|
strategy: 'fixed',
|