playbook_ui 14.20.0.pre.alpha.play2224scrollbarfix7991 → 14.20.0.pre.alpha.revert4453PBNTR933reactdraggablebugdragbtwnexamples7854

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 (49) hide show
  1. checksums.yaml +4 -4
  2. data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.scss +0 -18
  3. data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.tsx +0 -3
  4. data/app/pb_kits/playbook/pb_advanced_table/advanced_table.html.erb +8 -16
  5. data/app/pb_kits/playbook/pb_advanced_table/advanced_table.rb +0 -9
  6. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_beta.md +2 -6
  7. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_default.jsx +1 -5
  8. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_default.md +1 -1
  9. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_table_props.html.erb +1 -1
  10. data/app/pb_kits/playbook/pb_advanced_table/docs/example.yml +0 -2
  11. data/app/pb_kits/playbook/pb_advanced_table/index.js +12 -155
  12. data/app/pb_kits/playbook/pb_advanced_table/table_header.rb +0 -4
  13. data/app/pb_kits/playbook/pb_checkbox/checkbox.html.erb +12 -8
  14. data/app/pb_kits/playbook/pb_checkbox/checkbox.rb +6 -3
  15. data/app/pb_kits/playbook/pb_checkbox/docs/_checkbox_indeterminate.html.erb +48 -2
  16. data/app/pb_kits/playbook/pb_draggable/context/index.tsx +17 -58
  17. data/app/pb_kits/playbook/pb_dropdown/dropdown.test.jsx +2 -108
  18. data/app/pb_kits/playbook/pb_dropdown/index.js +0 -24
  19. data/app/pb_kits/playbook/pb_phone_number_input/_phone_number_input.tsx +0 -4
  20. data/app/pb_kits/playbook/pb_phone_number_input/docs/_phone_number_input_only_countries.jsx +1 -1
  21. data/app/pb_kits/playbook/pb_phone_number_input/docs/example.yml +3 -4
  22. data/app/pb_kits/playbook/pb_phone_number_input/docs/index.js +0 -1
  23. data/app/pb_kits/playbook/pb_phone_number_input/phone_number_input.rb +0 -3
  24. data/app/pb_kits/playbook/pb_select/docs/example.yml +0 -2
  25. data/app/pb_kits/playbook/pb_select/docs/index.js +0 -1
  26. data/dist/chunks/{_typeahead-CRW6dJbW.js → _typeahead-C-CI5Vgw.js} +2 -2
  27. data/dist/chunks/{_weekday_stacked-DoXl8xrB.js → _weekday_stacked-BCiM3zWM.js} +2 -2
  28. data/dist/chunks/vendor.js +1 -1
  29. data/dist/menu.yml +1 -1
  30. data/dist/playbook-doc.js +2 -2
  31. data/dist/playbook-rails-react-bindings.js +1 -1
  32. data/dist/playbook-rails.js +1 -1
  33. data/dist/playbook.css +1 -1
  34. data/lib/playbook/version.rb +1 -1
  35. metadata +4 -18
  36. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_selectable_rows_actions_rails.html.erb +0 -137
  37. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_selectable_rows_actions_rails.md +0 -3
  38. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_selectable_rows_header_rails.html.erb +0 -40
  39. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_selectable_rows_header_rails.md +0 -1
  40. data/app/pb_kits/playbook/pb_advanced_table/table_action_bar.html.erb +0 -23
  41. data/app/pb_kits/playbook/pb_advanced_table/table_action_bar.rb +0 -19
  42. data/app/pb_kits/playbook/pb_checkbox/docs/_checkbox_indeterminate_rails.md +0 -1
  43. data/app/pb_kits/playbook/pb_checkbox/index.js +0 -56
  44. data/app/pb_kits/playbook/pb_phone_number_input/docs/_phone_number_input_exclude_countries.html.erb +0 -4
  45. data/app/pb_kits/playbook/pb_phone_number_input/docs/_phone_number_input_exclude_countries.jsx +0 -15
  46. data/app/pb_kits/playbook/pb_phone_number_input/docs/_phone_number_input_exclude_countries.md +0 -1
  47. data/app/pb_kits/playbook/pb_select/docs/_select_custom_select_subheaders.html.erb +0 -12
  48. data/app/pb_kits/playbook/pb_select/docs/_select_custom_select_subheaders.jsx +0 -31
  49. data/app/pb_kits/playbook/pb_select/docs/_select_custom_select_subheaders.md +0 -1
@@ -1,11 +1,11 @@
1
- import React, { createContext, useReducer, useContext, useEffect, useMemo, useRef, useState } from "react";
1
+ import React, { createContext, useReducer, useContext, useEffect, useMemo } 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,23 +31,9 @@ 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 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);
34
+ const draggedIndex = newItems.indexOf(draggedItem);
45
35
  const targetIndex = newItems.findIndex(item => item.id === targetId);
46
36
 
47
- if (draggedIndex === -1 || targetIndex === -1) {
48
- return state;
49
- }
50
-
51
37
  newItems.splice(draggedIndex, 1);
52
38
  newItems.splice(targetIndex, 0, draggedItem);
53
39
 
@@ -62,11 +48,7 @@ const reducer = (state: InitialStateType, action: ActionType) => {
62
48
  const DragContext = createContext<any>({});
63
49
 
64
50
  export const DraggableContext = () => {
65
- const context = useContext(DragContext);
66
- if (context === undefined) {
67
- throw new Error('DraggableContext must be used within a DraggableProvider');
68
- }
69
- return context;
51
+ return useContext(DragContext);
70
52
  };
71
53
 
72
54
  export const DraggableProvider = ({
@@ -81,11 +63,7 @@ export const DraggableProvider = ({
81
63
  dropZone = { type: 'ghost', color: 'neutral', direction: 'vertical' }
82
64
  }: DraggableProviderType) => {
83
65
  const [state, dispatch] = useReducer(reducer, initialState);
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
-
66
+
89
67
  // Parse dropZone prop - handle both string format (backward compatibility) and object format
90
68
  let dropZoneType = 'ghost';
91
69
  let dropZoneColor = 'neutral';
@@ -108,64 +86,45 @@ export const DraggableProvider = ({
108
86
 
109
87
  useEffect(() => {
110
88
  dispatch({ type: 'SET_ITEMS', payload: initialItems });
111
- initialItemsRef.current = initialItems;
112
89
  }, [initialItems]);
113
90
 
114
91
  useEffect(() => {
115
- if (onReorder) {
116
- onReorder(state.items);
117
- }
118
- }, [state.items, onReorder]);
92
+ onReorder(state.items);
93
+ }, [state.items]);
119
94
 
120
95
  const handleDragStart = (id: string, container: string) => {
121
- setIsDragging(true);
122
- dispatch({ type: 'SET_DRAG_DATA', payload: { id, initialGroup: container } });
96
+ dispatch({ type: 'SET_DRAG_DATA', payload: { id: id, initialGroup: container } });
123
97
  dispatch({ type: 'SET_IS_DRAGGING', payload: id });
124
- dispatch({ type: 'SET_ACTIVE_CONTAINER', payload: container });
125
98
  if (onDragStart) onDragStart(id, container);
126
99
  };
127
100
 
128
101
  const handleDragEnter = (id: string, container: string) => {
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;
102
+ if (state.dragData.id !== id) {
103
+ dispatch({ type: 'REORDER_ITEMS', payload: { dragId: state.dragData.id, targetId: id } });
104
+ dispatch({ type: 'SET_DRAG_DATA', payload: { id: state.dragData.id, initialGroup: container } });
138
105
  }
139
-
140
- dispatch({ type: 'REORDER_ITEMS', payload: { dragId: state.dragData.id, targetId: id } });
141
-
142
106
  if (onDragEnter) onDragEnter(id, container);
143
107
  };
144
108
 
145
109
  const handleDragEnd = () => {
146
- setIsDragging(false);
147
110
  dispatch({ type: 'SET_IS_DRAGGING', payload: "" });
148
111
  dispatch({ type: 'SET_ACTIVE_CONTAINER', payload: "" });
149
112
  if (onDragEnd) onDragEnd();
150
113
  };
151
114
 
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
- }
115
+ const changeCategory = (itemId: string, container: string) => {
116
+ dispatch({ type: 'CHANGE_CATEGORY', payload: { itemId, container } });
117
+ };
158
118
 
119
+ const handleDrop = (container: string) => {
159
120
  dispatch({ type: 'SET_IS_DRAGGING', payload: "" });
160
121
  dispatch({ type: 'SET_ACTIVE_CONTAINER', payload: "" });
161
-
162
- setIsDragging(false);
122
+ changeCategory(state.dragData.id, container);
163
123
  if (onDrop) onDrop(container);
164
124
  };
165
125
 
166
126
  const handleDragOver = (e: Event, container: string) => {
167
127
  e.preventDefault();
168
- e.stopPropagation();
169
128
  dispatch({ type: 'SET_ACTIVE_CONTAINER', payload: container });
170
129
  if (onDragOver) onDragOver(e, container);
171
130
  };
@@ -185,7 +144,7 @@ export const DraggableProvider = ({
185
144
  handleDragEnd,
186
145
  handleDrop,
187
146
  handleDragOver
188
- }), [state, dropZoneType, dropZoneColor, dropZoneDirection, handleDragStart, handleDragEnter, handleDragEnd, handleDrop, handleDragOver]);
147
+ }), [state, dropZoneType, dropZoneColor, dropZoneDirection]);
189
148
 
190
149
  return (
191
150
  <DragContext.Provider value={contextValue}>{children}</DragContext.Provider>
@@ -1,5 +1,5 @@
1
1
  import React from "react"
2
- import { render, screen, fireEvent } from "../utilities/test-utils"
2
+ import { render, screen } from "../utilities/test-utils"
3
3
 
4
4
  import { Dropdown, Icon, IconCircle } from 'playbook-ui'
5
5
 
@@ -263,110 +263,4 @@ test("searchbar prop to render TextInput in container", () => {
263
263
  const kit = screen.getByTestId(testId)
264
264
  const searchbar = kit.querySelector('.pb_text_input_kit')
265
265
  expect(searchbar).toBeInTheDocument()
266
- })
267
-
268
- test("MultiSelect prop to allow multiple selections + add correct Form Pills", () => {
269
- render(
270
- <Dropdown
271
- data={{ testid: testId }}
272
- multiSelect
273
- options={options}
274
- />
275
- );
276
-
277
- const kit = screen.getByTestId(testId);
278
- const option = Array.from(kit.querySelectorAll(".pb_dropdown_option_list"));
279
- fireEvent.click(option[0]); // Select first option
280
- fireEvent.click(option[1]); // Select second option
281
- const formPills = kit.querySelectorAll(".pb_form_pill_kit_primary");
282
- expect(formPills.length).toBe(2);
283
- expect(formPills[0]).toHaveTextContent("United States");
284
- expect(formPills[1]).toHaveTextContent("Canada");
285
- });
286
-
287
- test("hides each selected option from the dropdown", () => {
288
-
289
- render(
290
- <Dropdown
291
- data={{ testid: testId }}
292
- multiSelect
293
- options={options}
294
- />
295
- );
296
-
297
- const kit = screen.getByTestId(testId);
298
- const option = Array.from(kit.querySelectorAll(".pb_dropdown_option_list"));
299
- const firstOpt = options[0].label
300
- fireEvent.click(option[0]);
301
- const option2 = Array.from(kit.querySelectorAll(".pb_dropdown_option_list"));
302
- expect(option2[0]).not.toHaveTextContent(firstOpt)
303
- })
304
-
305
- test("renders form pills inside trigger", () => {
306
- render(
307
- <Dropdown
308
- data={{ testid: testId }}
309
- multiSelect
310
- options={options}
311
- />
312
- );
313
-
314
- const kit = screen.getByTestId(testId)
315
- const option = kit.querySelector('.pb_dropdown_option_list')
316
- fireEvent.click(option)
317
- const formPill = kit.querySelector(".pb_form_pill_kit_primary")
318
- expect(formPill).toBeInTheDocument()
319
- })
320
-
321
- test("multiSelect and autocomplete to work together", () => {
322
- render (
323
- <Dropdown
324
- autocomplete
325
- data={{ testid: testId }}
326
- multiSelect
327
- options={options}
328
- />
329
- )
330
-
331
- const kit = screen.getByTestId(testId)
332
- const input = kit.querySelector('.dropdown_input')
333
- expect(input).toBeInTheDocument()
334
- const option = kit.querySelector('.pb_dropdown_option_list')
335
- fireEvent.click(option)
336
- const formPill = kit.querySelector(".pb_form_pill_kit_primary")
337
- expect(formPill).toBeInTheDocument()
338
- })
339
-
340
- test("renders form pills with size and color", () => {
341
- render(
342
- <Dropdown
343
- data={{ testid: testId }}
344
- formPillProps={{ size: "small", color: "neutral" }}
345
- multiSelect
346
- options={options}
347
- />
348
- );
349
-
350
- const kit = screen.getByTestId(testId)
351
- const option = kit.querySelector('.pb_dropdown_option_list')
352
- fireEvent.click(option)
353
- const formPill = kit.querySelector(".pb_form_pill_kit_neutral")
354
- expect(formPill).toBeInTheDocument()
355
- expect(formPill).toHaveClass("small")
356
- })
357
-
358
- test("defaultValue works with multiSelect", () => {
359
- render(
360
- <Dropdown
361
- data={{ testid: testId }}
362
- defaultValue={[options[0], options[2]]}
363
- multiSelect
364
- options={options}
365
- />
366
- )
367
- const kit = screen.getByTestId(testId)
368
- expect(kit.querySelectorAll(".pb_form_pill_kit_primary")).toHaveLength(2)
369
- const option2 = Array.from(kit.querySelectorAll(".pb_dropdown_option_list"));
370
- const firstOpt = options[0].label
371
- expect(option2[0]).not.toHaveTextContent(firstOpt)
372
- })
266
+ })
@@ -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) {
@@ -33,7 +33,6 @@ type PhoneNumberInputProps = {
33
33
  onChange?: (e: React.FormEvent<HTMLInputElement>) => void,
34
34
  onValidate?: Callback<boolean, void>,
35
35
  onlyCountries: string[],
36
- excludeCountries: string[],
37
36
  preferredCountries?: string[],
38
37
  required?: boolean,
39
38
  value?: string,
@@ -89,7 +88,6 @@ const PhoneNumberInput = (props: PhoneNumberInputProps, ref?: React.MutableRefOb
89
88
  },
90
89
  onValidate = () => null,
91
90
  onlyCountries = [],
92
- excludeCountries = [],
93
91
  required = false,
94
92
  preferredCountries = [],
95
93
  value = "",
@@ -236,7 +234,6 @@ const PhoneNumberInput = (props: PhoneNumberInputProps, ref?: React.MutableRefOb
236
234
  const fallbackCountry =
237
235
  preferredCountries.length > 0 ? preferredCountries[0] :
238
236
  onlyCountries.length > 0 ? onlyCountries.sort()[0] :
239
- excludeCountries.length > 0 ? excludeCountries.sort()[0] :
240
237
  "af";
241
238
 
242
239
  useEffect(() => {
@@ -247,7 +244,6 @@ const PhoneNumberInput = (props: PhoneNumberInputProps, ref?: React.MutableRefOb
247
244
  autoInsertDialCode: false,
248
245
  initialCountry: initialCountry || fallbackCountry,
249
246
  onlyCountries,
250
- excludeCountries,
251
247
  countrySearch: countrySearch,
252
248
  fixDropdownWidth: false,
253
249
  formatAsYouType: formatAsYouType,
@@ -6,7 +6,7 @@ const PhoneNumberInputOnlyCountries = (props) => (
6
6
  <PhoneNumberInput
7
7
  id='only'
8
8
  onlyCountries={['us', 'br']}
9
- {...props}
9
+ {...props}
10
10
  />
11
11
  </>
12
12
  )
@@ -4,8 +4,7 @@ examples:
4
4
  - phone_number_input_default: Default
5
5
  - phone_number_input_preferred_countries: Preferred Countries
6
6
  - phone_number_input_initial_country: Initial Country
7
- - phone_number_input_only_countries: Only Countries
8
- - phone_number_input_exclude_countries: Exclude Countries
7
+ - phone_number_input_only_countries: Limited Countries
9
8
  - phone_number_input_validation: Form Validation
10
9
  - phone_number_input_clear_field: Clearing the Input Field
11
10
  - phone_number_input_access_input_element: Accessing the Input Element
@@ -16,9 +15,9 @@ examples:
16
15
  - phone_number_input_default: Default
17
16
  - phone_number_input_preferred_countries: Preferred Countries
18
17
  - phone_number_input_initial_country: Initial Country
19
- - phone_number_input_only_countries: Only Countries
20
- - phone_number_input_exclude_countries: Exclude Countries
18
+ - phone_number_input_only_countries: Limited Countries
21
19
  - phone_number_input_validation: Form Validation
22
20
  - phone_number_input_format: Format as You Type
23
21
  - phone_number_input_hidden_inputs: Hidden Inputs
24
22
  - phone_number_input_country_search: Country Search
23
+
@@ -2,7 +2,6 @@ export { default as PhoneNumberInputDefault } from './_phone_number_input_defaul
2
2
  export { default as PhoneNumberInputPreferredCountries } from './_phone_number_input_preferred_countries'
3
3
  export { default as PhoneNumberInputInitialCountry } from './_phone_number_input_initial_country'
4
4
  export { default as PhoneNumberInputOnlyCountries } from './_phone_number_input_only_countries'
5
- export { default as PhoneNumberInputExcludeCountries } from './_phone_number_input_exclude_countries'
6
5
  export { default as PhoneNumberInputValidation } from './_phone_number_input_validation'
7
6
  export { default as PhoneNumberInputClearField } from './_phone_number_input_clear_field'
8
7
  export { default as PhoneNumberInputAccessInputElement } from './_phone_number_input_access_input_element'
@@ -15,8 +15,6 @@ module Playbook
15
15
  default: ""
16
16
  prop :only_countries, type: Playbook::Props::Array,
17
17
  default: []
18
- prop :exclude_countries, type: Playbook::Props::Array,
19
- default: []
20
18
  prop :preferred_countries, type: Playbook::Props::Array,
21
19
  default: []
22
20
  prop :error, type: Playbook::Props::String,
@@ -46,7 +44,6 @@ module Playbook
46
44
  label: label,
47
45
  name: name,
48
46
  onlyCountries: only_countries,
49
- excludeCountries: exclude_countries,
50
47
  preferredCountries: preferred_countries,
51
48
  required: required,
52
49
  value: value,
@@ -8,7 +8,6 @@ examples:
8
8
  - select_required: Required Select Field
9
9
  - select_value_text_same: Equal option value and value text
10
10
  - select_custom_select: Custom Select
11
- - select_custom_select_subheaders: Custom Select Subheaders
12
11
  - select_error: Select w/ Error
13
12
  - select_inline: Select Inline
14
13
  - select_inline_show_arrow: Select Inline (Always Show Arrow)
@@ -26,7 +25,6 @@ examples:
26
25
  - select_required: Required Select Field
27
26
  - select_value_text_same: Equal option value and value text
28
27
  - select_custom_select: Custom Select
29
- - select_custom_select_subheaders: Custom Select Subheaders
30
28
  - select_error: Select w/ Error
31
29
  - select_inline: Select Inline
32
30
  - select_inline_show_arrow: Select Inline (Always Show Arrow)
@@ -11,4 +11,3 @@ export { default as SelectInlineShowArrow } from './_select_inline_show_arrow.js
11
11
  export { default as SelectInlineCompact } from './_select_inline_compact.jsx'
12
12
  export { default as SelectMultiple } from './_select_multiple.jsx'
13
13
  export { default as SelectReactHook } from './_select_react_hook.jsx'
14
- export { default as SelectCustomSelectSubheaders } from './_select_custom_select_subheaders.jsx'