playbook_ui 16.1.0.pre.alpha.play276813969 → 16.1.0.pre.alpha.play277814027

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 (52) hide show
  1. checksums.yaml +4 -4
  2. data/app/pb_kits/playbook/pb_advanced_table/Components/RegularTableView.tsx +12 -2
  3. data/app/pb_kits/playbook/pb_advanced_table/advanced_table.test.jsx +33 -0
  4. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_styling_background_custom.jsx +71 -0
  5. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_styling_background_custom.md +4 -0
  6. data/app/pb_kits/playbook/pb_advanced_table/docs/example.yml +1 -0
  7. data/app/pb_kits/playbook/pb_advanced_table/docs/index.js +2 -1
  8. data/app/pb_kits/playbook/pb_date_picker/_date_picker.tsx +14 -5
  9. data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_default.md +1 -0
  10. data/app/pb_kits/playbook/pb_dropdown/_dropdown.tsx +11 -46
  11. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_label.html.erb +3 -6
  12. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_label.jsx +0 -1
  13. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_label.md +1 -3
  14. data/app/pb_kits/playbook/pb_dropdown/dropdown.html.erb +4 -10
  15. data/app/pb_kits/playbook/pb_dropdown/dropdown.rb +0 -9
  16. data/app/pb_kits/playbook/pb_dropdown/dropdown_trigger.html.erb +2 -7
  17. data/app/pb_kits/playbook/pb_dropdown/dropdown_trigger.rb +0 -4
  18. data/app/pb_kits/playbook/pb_dropdown/index.js +73 -125
  19. data/app/pb_kits/playbook/pb_dropdown/subcomponents/DropdownTrigger.tsx +0 -16
  20. data/app/pb_kits/playbook/pb_dropdown/utilities/clickOutsideHelper.tsx +0 -6
  21. data/app/pb_kits/playbook/pb_form/docs/_form_with_required_indicator.html.erb +1 -0
  22. data/app/pb_kits/playbook/pb_form/pb_form_validation.js +9 -2
  23. data/app/pb_kits/playbook/pb_multi_level_select/_multi_level_select.scss +0 -7
  24. data/app/pb_kits/playbook/pb_multi_level_select/_multi_level_select.tsx +549 -638
  25. data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_label.html.erb +3 -3
  26. data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_label.jsx +7 -4
  27. data/app/pb_kits/playbook/pb_multi_level_select/multi_level_select.test.jsx +4 -4
  28. data/app/pb_kits/playbook/pb_textarea/_textarea.tsx +10 -0
  29. data/app/pb_kits/playbook/pb_textarea/docs/_textarea_default.html.erb +3 -3
  30. data/app/pb_kits/playbook/pb_textarea/docs/_textarea_default.jsx +3 -0
  31. data/app/pb_kits/playbook/pb_textarea/docs/_textarea_default.md +1 -0
  32. data/app/pb_kits/playbook/pb_textarea/textarea.html.erb +25 -9
  33. data/app/pb_kits/playbook/pb_textarea/textarea.rb +7 -1
  34. data/app/pb_kits/playbook/pb_time_picker/_time_picker.tsx +97 -11
  35. data/app/pb_kits/playbook/pb_time_picker/docs/_time_picker_on_handler.jsx +5 -2
  36. data/app/pb_kits/playbook/pb_time_picker/docs/_time_picker_required_indicator.html.erb +6 -0
  37. data/app/pb_kits/playbook/pb_time_picker/docs/_time_picker_required_indicator.jsx +16 -0
  38. data/app/pb_kits/playbook/pb_time_picker/docs/_time_picker_required_indicator.md +3 -0
  39. data/app/pb_kits/playbook/pb_time_picker/docs/example.yml +2 -0
  40. data/app/pb_kits/playbook/pb_time_picker/docs/index.js +1 -0
  41. data/app/pb_kits/playbook/pb_time_picker/time_picker.rb +3 -0
  42. data/app/pb_kits/playbook/pb_time_picker/time_picker.test.jsx +47 -1
  43. data/dist/chunks/_typeahead-CWA5wlah.js +1 -0
  44. data/dist/chunks/vendor.js +3 -3
  45. data/dist/menu.yml +2 -2
  46. data/dist/playbook-rails-react-bindings.js +1 -1
  47. data/dist/playbook-rails.js +1 -1
  48. data/dist/playbook.css +1 -1
  49. data/lib/playbook/version.rb +1 -1
  50. metadata +10 -4
  51. data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_label.md +0 -3
  52. data/dist/chunks/_typeahead-C4YsbA48.js +0 -1
@@ -14,7 +14,6 @@ const DROPDOWN_INPUT = "#dropdown-selected-option";
14
14
  const SEARCH_INPUT_SELECTOR = "[data-dropdown-autocomplete]";
15
15
  const SEARCH_BAR_SELECTOR = "[data-dropdown-search]";
16
16
  const CLEAR_ICON_SELECTOR = "#dropdown_clear_icon";
17
- const LABEL_SELECTOR = '[data-dropdown="pb-dropdown-label"]';
18
17
 
19
18
  export default class PbDropdown extends PbEnhancedElement {
20
19
  static get selector() {
@@ -31,15 +30,14 @@ export default class PbDropdown extends PbEnhancedElement {
31
30
  connect() {
32
31
  // Store instance on element for DatePicker sync
33
32
  this.element._pbDropdownInstance = this;
34
-
33
+
35
34
  this.keyboardHandler = new PbDropdownKeyboard(this);
36
35
  this.isMultiSelect = this.element.dataset.pbDropdownMultiSelect === "true";
37
36
  this.formPillProps = this.element.dataset.formPillProps
38
37
  ? JSON.parse(this.element.dataset.formPillProps)
39
38
  : {};
40
39
  const baseInput = this.element.querySelector(DROPDOWN_INPUT);
41
- this.wasOriginallyRequired =
42
- baseInput && baseInput.hasAttribute("required");
40
+ this.wasOriginallyRequired = baseInput && baseInput.hasAttribute("required");
43
41
  this.setDefaultValue();
44
42
  this.bindEventListeners();
45
43
  this.bindSearchInput();
@@ -77,24 +75,15 @@ export default class PbDropdown extends PbEnhancedElement {
77
75
  bindEventListeners() {
78
76
  const customTrigger =
79
77
  this.element.querySelector(CUSTOM_DISPLAY_SELECTOR) || this.element;
80
- customTrigger.addEventListener("click", (e) => {
81
- const label = e.target.closest(LABEL_SELECTOR);
82
- if (label && label.htmlFor) {
83
- const trigger = this.element.querySelector(
84
- `#${CSS.escape(label.htmlFor)}`,
85
- );
86
- if (trigger) {
87
- trigger.focus();
88
- }
89
- }
90
- this.toggleElement(this.target);
91
- });
78
+ customTrigger.addEventListener("click", () =>
79
+ this.toggleElement(this.target)
80
+ );
92
81
 
93
82
  this.target.addEventListener("click", this.handleOptionClick.bind(this));
94
83
  document.addEventListener(
95
84
  "click",
96
85
  this.handleDocumentClick.bind(this),
97
- true,
86
+ true
98
87
  );
99
88
  }
100
89
 
@@ -103,7 +92,7 @@ export default class PbDropdown extends PbEnhancedElement {
103
92
  if (!this.searchBar) return;
104
93
 
105
94
  this.searchBar.addEventListener("input", (e) =>
106
- this.handleSearch(e.target.value),
95
+ this.handleSearch(e.target.value)
107
96
  );
108
97
  }
109
98
 
@@ -118,7 +107,7 @@ export default class PbDropdown extends PbEnhancedElement {
118
107
 
119
108
  // Live filter
120
109
  this.searchInput.addEventListener("input", (e) =>
121
- this.handleSearch(e.target.value),
110
+ this.handleSearch(e.target.value)
122
111
  );
123
112
  }
124
113
 
@@ -172,31 +161,28 @@ export default class PbDropdown extends PbEnhancedElement {
172
161
 
173
162
  handleSearch(term = "") {
174
163
  const lcTerm = term.toLowerCase();
175
- let hasMatch = false;
164
+ let hasMatch = false
176
165
  this.element.querySelectorAll(OPTION_SELECTOR).forEach((opt) => {
177
166
  //make it so that if the option is selected, it will not show up in the search results
178
- if (
179
- this.isMultiSelect &&
180
- this.selectedOptions.has(opt.dataset.dropdownOptionLabel)
181
- ) {
182
- opt.style.display = "none";
183
- return;
184
- }
167
+ if (this.isMultiSelect && this.selectedOptions.has(opt.dataset.dropdownOptionLabel)) {
168
+ opt.style.display = "none";
169
+ return;
170
+ }
185
171
  const label = JSON.parse(opt.dataset.dropdownOptionLabel)
186
172
  .label.toString()
187
173
  .toLowerCase();
188
174
 
189
- // hide or show option
175
+ // hide or show option
190
176
  const match = label.includes(lcTerm);
191
177
  opt.style.display = match ? "" : "none";
192
- if (match) hasMatch = true;
178
+ if (match) hasMatch = true
193
179
  });
194
180
 
195
181
  this.adjustDropdownHeight();
196
182
 
197
- this.removeNoOptionsMessage();
183
+ this.removeNoOptionsMessage()
198
184
  if (!hasMatch) {
199
- this.showNoOptionsMessage();
185
+ this.showNoOptionsMessage()
200
186
  }
201
187
  }
202
188
 
@@ -204,8 +190,7 @@ export default class PbDropdown extends PbEnhancedElement {
204
190
  if (this.element.querySelector(".dropdown_no_options")) return;
205
191
 
206
192
  const noOptionElement = document.createElement("div");
207
- noOptionElement.className =
208
- "pb_body_kit_light dropdown_no_options pb_item_kit p_xs display_flex justify_content_center";
193
+ noOptionElement.className = "pb_body_kit_light dropdown_no_options pb_item_kit p_xs display_flex justify_content_center";
209
194
  noOptionElement.textContent = "no option";
210
195
 
211
196
  this.target.appendChild(noOptionElement);
@@ -256,8 +241,6 @@ export default class PbDropdown extends PbEnhancedElement {
256
241
  }
257
242
 
258
243
  isClickOutside(event) {
259
- const label = event.target.closest(LABEL_SELECTOR);
260
- if (label && this.element.contains(label)) return false;
261
244
  const customTrigger = this.element.querySelector(CUSTOM_DISPLAY_SELECTOR);
262
245
  if (customTrigger) {
263
246
  return !customTrigger.contains(event.target);
@@ -288,8 +271,8 @@ export default class PbDropdown extends PbEnhancedElement {
288
271
  ? JSON.parse(
289
272
  this.element.querySelector(
290
273
  OPTION_SELECTOR +
291
- `[data-dropdown-option-label*='"id":"${hiddenInput.value}"']`,
292
- ).dataset.dropdownOptionLabel,
274
+ `[data-dropdown-option-label*='"id":"${hiddenInput.value}"']`
275
+ ).dataset.dropdownOptionLabel
293
276
  )
294
277
  : null;
295
278
  }
@@ -298,14 +281,14 @@ export default class PbDropdown extends PbEnhancedElement {
298
281
  new CustomEvent("pb:dropdown:selected", {
299
282
  detail,
300
283
  bubbles: true,
301
- }),
284
+ })
302
285
  );
303
286
  }
304
287
 
305
288
  onOptionSelected(value, selectedOption) {
306
289
  const triggerElement = this.element.querySelector(DROPDOWN_TRIGGER_DISPLAY);
307
290
  const customDisplayElement = this.element.querySelector(
308
- "#dropdown_trigger_custom_display",
291
+ "#dropdown_trigger_custom_display"
309
292
  );
310
293
 
311
294
  if (triggerElement) {
@@ -313,46 +296,36 @@ export default class PbDropdown extends PbEnhancedElement {
313
296
  const selectedLabel = JSON.parse(value).label;
314
297
  triggerElement.textContent = selectedLabel;
315
298
  this.emitSelectionChange();
316
-
299
+
317
300
  // Handle quickpick variant: populate start/end date hidden inputs
318
301
  const optionData = JSON.parse(value);
319
302
  const startDateId = this.element.dataset.startDateId;
320
303
  const endDateId = this.element.dataset.endDateId;
321
304
  const controlsStartId = this.element.dataset.controlsStartId;
322
305
  const controlsEndId = this.element.dataset.controlsEndId;
323
-
306
+
324
307
  if (optionData.formatted_start_date && optionData.formatted_end_date) {
325
308
  // Populate date inputs when option has date fields
326
309
  if (startDateId) {
327
310
  const startDateInput = document.getElementById(startDateId);
328
- if (startDateInput)
329
- startDateInput.value = optionData.formatted_start_date;
311
+ if (startDateInput) startDateInput.value = optionData.formatted_start_date;
330
312
  }
331
-
313
+
332
314
  if (endDateId) {
333
315
  const endDateInput = document.getElementById(endDateId);
334
- if (endDateInput)
335
- endDateInput.value = optionData.formatted_end_date;
316
+ if (endDateInput) endDateInput.value = optionData.formatted_end_date;
336
317
  }
337
-
318
+
338
319
  // Sync with DatePickers if controlsStartId/controlsEndId are present
339
320
  if (controlsStartId) {
340
- const startPicker = document.querySelector(
341
- `#${controlsStartId}`,
342
- )?._flatpickr;
321
+ const startPicker = document.querySelector(`#${controlsStartId}`)?._flatpickr;
343
322
  if (startPicker) {
344
- startPicker.setDate(
345
- optionData.formatted_start_date,
346
- true,
347
- "m/d/Y",
348
- );
323
+ startPicker.setDate(optionData.formatted_start_date, true, "m/d/Y");
349
324
  }
350
325
  }
351
-
326
+
352
327
  if (controlsEndId) {
353
- const endPicker = document.querySelector(
354
- `#${controlsEndId}`,
355
- )?._flatpickr;
328
+ const endPicker = document.querySelector(`#${controlsEndId}`)?._flatpickr;
356
329
  if (endPicker) {
357
330
  endPicker.setDate(optionData.formatted_end_date, true, "m/d/Y");
358
331
  }
@@ -363,26 +336,22 @@ export default class PbDropdown extends PbEnhancedElement {
363
336
  const startDateInput = document.getElementById(startDateId);
364
337
  if (startDateInput) startDateInput.value = "";
365
338
  }
366
-
339
+
367
340
  if (endDateId) {
368
341
  const endDateInput = document.getElementById(endDateId);
369
342
  if (endDateInput) endDateInput.value = "";
370
343
  }
371
-
344
+
372
345
  // Clear DatePickers as well
373
346
  if (controlsStartId) {
374
- const startPicker = document.querySelector(
375
- `#${controlsStartId}`,
376
- )?._flatpickr;
347
+ const startPicker = document.querySelector(`#${controlsStartId}`)?._flatpickr;
377
348
  if (startPicker) {
378
349
  startPicker.clear();
379
350
  }
380
351
  }
381
-
352
+
382
353
  if (controlsEndId) {
383
- const endPicker = document.querySelector(
384
- `#${controlsEndId}`,
385
- )?._flatpickr;
354
+ const endPicker = document.querySelector(`#${controlsEndId}`)?._flatpickr;
386
355
  if (endPicker) {
387
356
  endPicker.clear();
388
357
  }
@@ -422,9 +391,7 @@ export default class PbDropdown extends PbEnhancedElement {
422
391
  this.adjustDropdownHeight();
423
392
  }
424
393
  });
425
- this.element.querySelector(DROPDOWN_INPUT).value = Array.from(
426
- this.selectedOptions,
427
- )
394
+ this.element.querySelector(DROPDOWN_INPUT).value = Array.from(this.selectedOptions)
428
395
  .map((opt) => JSON.parse(opt).id)
429
396
  .join(",");
430
397
  } else {
@@ -470,7 +437,7 @@ export default class PbDropdown extends PbEnhancedElement {
470
437
  this.keyboardHandler.focusedOptionIndex = -1;
471
438
  const options = this.element.querySelectorAll(OPTION_SELECTOR);
472
439
  options.forEach((option) =>
473
- option.classList.remove("pb_dropdown_option_focused"),
440
+ option.classList.remove("pb_dropdown_option_focused")
474
441
  );
475
442
  }
476
443
  }
@@ -505,7 +472,7 @@ export default class PbDropdown extends PbEnhancedElement {
505
472
  hiddenInput.closest(".dropdown_wrapper").classList.add("error");
506
473
  }
507
474
  },
508
- true,
475
+ true
509
476
  );
510
477
  }
511
478
 
@@ -515,7 +482,7 @@ export default class PbDropdown extends PbEnhancedElement {
515
482
  const dropdownWrapperElement = input.closest(".dropdown_wrapper");
516
483
  dropdownWrapperElement.classList.remove("error");
517
484
  const errorLabelElement = dropdownWrapperElement.querySelector(
518
- ".pb_body_kit_negative",
485
+ ".pb_body_kit_negative"
519
486
  );
520
487
  if (errorLabelElement) {
521
488
  errorLabelElement.remove();
@@ -523,13 +490,13 @@ export default class PbDropdown extends PbEnhancedElement {
523
490
  return;
524
491
  }
525
492
  }
526
-
493
+
527
494
  if (input.checkValidity()) {
528
495
  const dropdownWrapperElement = input.closest(".dropdown_wrapper");
529
496
  dropdownWrapperElement.classList.remove("error");
530
497
 
531
498
  const errorLabelElement = dropdownWrapperElement.querySelector(
532
- ".pb_body_kit_negative",
499
+ ".pb_body_kit_negative"
533
500
  );
534
501
  if (errorLabelElement) {
535
502
  errorLabelElement.remove();
@@ -540,7 +507,7 @@ export default class PbDropdown extends PbEnhancedElement {
540
507
  setDefaultValue() {
541
508
  const hiddenInput = this.element.querySelector(DROPDOWN_INPUT);
542
509
  const optionEls = Array.from(
543
- this.element.querySelectorAll(OPTION_SELECTOR),
510
+ this.element.querySelectorAll(OPTION_SELECTOR)
544
511
  );
545
512
  const defaultValue = hiddenInput.dataset.defaultValue || "";
546
513
  if (!defaultValue) return;
@@ -586,53 +553,44 @@ export default class PbDropdown extends PbEnhancedElement {
586
553
  selectedOption.classList.add("pb_dropdown_option_selected");
587
554
  const optionData = JSON.parse(selectedOption.dataset.dropdownOptionLabel);
588
555
  this.setTriggerElementText(optionData.label);
589
-
556
+
590
557
  // Handle quickpick variant: populate start/end date hidden inputs and sync DatePickers
591
558
  if (optionData.formatted_start_date && optionData.formatted_end_date) {
592
559
  const startDateId = this.element.dataset.startDateId;
593
560
  const endDateId = this.element.dataset.endDateId;
594
561
  const controlsStartId = this.element.dataset.controlsStartId;
595
562
  const controlsEndId = this.element.dataset.controlsEndId;
596
-
563
+
597
564
  if (startDateId) {
598
565
  const startDateInput = document.getElementById(startDateId);
599
- if (startDateInput)
600
- startDateInput.value = optionData.formatted_start_date;
566
+ if (startDateInput) startDateInput.value = optionData.formatted_start_date;
601
567
  }
602
-
568
+
603
569
  if (endDateId) {
604
570
  const endDateInput = document.getElementById(endDateId);
605
571
  if (endDateInput) endDateInput.value = optionData.formatted_end_date;
606
572
  }
607
-
573
+
608
574
  // Sync with DatePickers - retry with delays to ensure DatePickers are initialized
609
575
  const syncDatePickers = () => {
610
576
  if (controlsStartId) {
611
- const startPicker = document.querySelector(
612
- `#${controlsStartId}`,
613
- )?._flatpickr;
577
+ const startPicker = document.querySelector(`#${controlsStartId}`)?._flatpickr;
614
578
  if (startPicker) {
615
- startPicker.setDate(
616
- optionData.formatted_start_date,
617
- true,
618
- "m/d/Y",
619
- );
579
+ startPicker.setDate(optionData.formatted_start_date, true, "m/d/Y");
620
580
  }
621
581
  }
622
-
582
+
623
583
  if (controlsEndId) {
624
- const endPicker = document.querySelector(
625
- `#${controlsEndId}`,
626
- )?._flatpickr;
584
+ const endPicker = document.querySelector(`#${controlsEndId}`)?._flatpickr;
627
585
  if (endPicker) {
628
586
  endPicker.setDate(optionData.formatted_end_date, true, "m/d/Y");
629
587
  }
630
588
  }
631
589
  };
632
-
590
+
633
591
  // Try immediately
634
592
  syncDatePickers();
635
-
593
+
636
594
  // Retry after short delay in case DatePickers aren't ready yet
637
595
  setTimeout(syncDatePickers, 100);
638
596
  setTimeout(syncDatePickers, 300);
@@ -695,7 +653,7 @@ export default class PbDropdown extends PbEnhancedElement {
695
653
 
696
654
  const wrapper = this.element.querySelector("#dropdown_pills_wrapper");
697
655
  const placeholder = this.element.querySelector(
698
- "#dropdown_trigger_display_multi_select",
656
+ "#dropdown_trigger_display_multi_select"
699
657
  );
700
658
  if (!wrapper) return;
701
659
 
@@ -713,12 +671,7 @@ export default class PbDropdown extends PbEnhancedElement {
713
671
  // Create a form pill for each selected option
714
672
  const pill = document.createElement("div");
715
673
  const color = this.formPillProps.color || "primary";
716
- pill.classList.add(
717
- "pb_form_pill_kit",
718
- `pb_form_pill_${color}`,
719
- "pb_form_pill_none",
720
- "mr_xs",
721
- );
674
+ pill.classList.add("pb_form_pill_kit", `pb_form_pill_${color}`, "pb_form_pill_none", "mr_xs");
722
675
  if (this.formPillProps.size === "small") {
723
676
  pill.classList.add("pb_form_pill_small");
724
677
  }
@@ -743,8 +696,8 @@ export default class PbDropdown extends PbEnhancedElement {
743
696
 
744
697
  const optEl = this.element.querySelector(
745
698
  `${OPTION_SELECTOR}[data-dropdown-option-label*='"id":${JSON.stringify(
746
- id,
747
- )}']`,
699
+ id
700
+ )}']`
748
701
  );
749
702
  if (optEl) {
750
703
  optEl.style.display = "";
@@ -773,18 +726,18 @@ export default class PbDropdown extends PbEnhancedElement {
773
726
  }
774
727
  }
775
728
  const customDisplay = this.element.querySelector(
776
- "#dropdown_trigger_custom_display",
729
+ "#dropdown_trigger_custom_display"
777
730
  );
778
731
  if (customDisplay) {
779
732
  customDisplay.style.display = "none";
780
733
  }
781
-
734
+
782
735
  // Clear quickpick hidden inputs
783
736
  const startDateId = this.element.dataset.startDateId;
784
737
  const endDateId = this.element.dataset.endDateId;
785
738
  const controlsStartId = this.element.dataset.controlsStartId;
786
739
  const controlsEndId = this.element.dataset.controlsEndId;
787
-
740
+
788
741
  if (startDateId) {
789
742
  const startDateInput = document.getElementById(startDateId);
790
743
  if (startDateInput) startDateInput.value = "";
@@ -793,24 +746,22 @@ export default class PbDropdown extends PbEnhancedElement {
793
746
  const endDateInput = document.getElementById(endDateId);
794
747
  if (endDateInput) endDateInput.value = "";
795
748
  }
796
-
749
+
797
750
  // Clear linked DatePickers if controlsStartId/controlsEndId are present
798
751
  if (controlsStartId) {
799
- const startPicker = document.querySelector(
800
- `#${controlsStartId}`,
801
- )?._flatpickr;
752
+ const startPicker = document.querySelector(`#${controlsStartId}`)?._flatpickr;
802
753
  if (startPicker) {
803
754
  startPicker.clear();
804
755
  }
805
756
  }
806
-
757
+
807
758
  if (controlsEndId) {
808
759
  const endPicker = document.querySelector(`#${controlsEndId}`)?._flatpickr;
809
760
  if (endPicker) {
810
761
  endPicker.clear();
811
762
  }
812
763
  }
813
-
764
+
814
765
  this.resetDropdownValue();
815
766
  this.updatePills();
816
767
  this.updateClearButton();
@@ -821,24 +772,21 @@ export default class PbDropdown extends PbEnhancedElement {
821
772
  // Method for DatePicker sync - only clears the dropdown, not the DatePickers
822
773
  clearSelected() {
823
774
  // Only clear if this is a single-select quickpick variant
824
- if (
825
- this.element.dataset.pbDropdownVariant !== "quickpick" ||
826
- this.isMultiSelect
827
- ) {
775
+ if (this.element.dataset.pbDropdownVariant !== "quickpick" || this.isMultiSelect) {
828
776
  return;
829
777
  }
830
-
778
+
831
779
  const customDisplay = this.element.querySelector(
832
- "#dropdown_trigger_custom_display",
780
+ "#dropdown_trigger_custom_display"
833
781
  );
834
782
  if (customDisplay) {
835
783
  customDisplay.style.display = "none";
836
784
  }
837
-
785
+
838
786
  // Clear quickpick hidden inputs only (not the DatePickers)
839
787
  const startDateId = this.element.dataset.startDateId;
840
788
  const endDateId = this.element.dataset.endDateId;
841
-
789
+
842
790
  if (startDateId) {
843
791
  const startDateInput = document.getElementById(startDateId);
844
792
  if (startDateInput) startDateInput.value = "";
@@ -847,7 +795,7 @@ export default class PbDropdown extends PbEnhancedElement {
847
795
  const endDateInput = document.getElementById(endDateId);
848
796
  if (endDateInput) endDateInput.value = "";
849
797
  }
850
-
798
+
851
799
  this.resetDropdownValue();
852
800
  this.updateClearButton();
853
801
  this.emitSelectionChange();
@@ -874,7 +822,7 @@ export default class PbDropdown extends PbEnhancedElement {
874
822
  inp.dataset.generated = "true";
875
823
  baseInput.insertAdjacentElement("afterend", inp);
876
824
  });
877
-
825
+
878
826
  // For multi-select, remove required from base input when there are selections
879
827
  // The generated inputs handle the form submission with actual values
880
828
  // Restore required attribute when there are no selections (if it was originally required)
@@ -45,8 +45,6 @@ const DropdownTrigger = (props: DropdownTriggerProps) => {
45
45
  const {
46
46
  autocomplete,
47
47
  clearable,
48
- error,
49
- errorId,
50
48
  filterItem,
51
49
  handleBackspace,
52
50
  handleChange,
@@ -55,10 +53,8 @@ const DropdownTrigger = (props: DropdownTriggerProps) => {
55
53
  inputWrapperRef,
56
54
  isDropDownClosed,
57
55
  isInputFocused,
58
- label: contextLabel,
59
56
  multiSelect,
60
57
  selected,
61
- selectId,
62
58
  setIsInputFocused,
63
59
  toggleDropdown,
64
60
  } = useContext(DropdownContext);
@@ -108,10 +104,6 @@ const DropdownTrigger = (props: DropdownTriggerProps) => {
108
104
  ? placeholder
109
105
  : "Select...";
110
106
 
111
- const triggerAriaLabel = contextLabel
112
- ? (children ? contextLabel : `${contextLabel}, ${defaultDisplayPlaceholder}`)
113
- : undefined;
114
-
115
107
  return (
116
108
  <div {...ariaProps}
117
109
  {...dataProps}
@@ -122,10 +114,6 @@ const DropdownTrigger = (props: DropdownTriggerProps) => {
122
114
  {
123
115
  children ? (
124
116
  <div
125
- aria-describedby={errorId}
126
- aria-invalid={!!error}
127
- aria-label={triggerAriaLabel}
128
- id={selectId}
129
117
  onClick={() => toggleDropdown()}
130
118
  onKeyDown= {handleKeyDown}
131
119
  ref={inputWrapperRef}
@@ -142,10 +130,6 @@ const DropdownTrigger = (props: DropdownTriggerProps) => {
142
130
  className={triggerWrapperClasses}
143
131
  cursor={`${autocomplete ? "text" : "pointer"}`}
144
132
  htmlOptions={{
145
- "aria-describedby": errorId,
146
- "aria-invalid": !!error,
147
- "aria-label": triggerAriaLabel,
148
- id: selectId,
149
133
  onClick: () => handleWrapperClick(),
150
134
  onKeyDown: handleKeyDown,
151
135
  tabIndex: "0",
@@ -25,12 +25,6 @@ export const handleClickOutside =
25
25
  ) {
26
26
  shouldClose = false;
27
27
  }
28
- // Target dropdown container to open dropdown
29
- if (
30
- targetElement.getAttribute("data-dropdown") === "pb-dropdown-label"
31
- ) {
32
- shouldClose = false;
33
- }
34
28
  targetElement = targetElement.parentElement as HTMLElement;
35
29
  }
36
30
  if (
@@ -9,6 +9,7 @@
9
9
  <%= form.password_field :example_password_field, props: { label: true, required: true, required_indicator: true } %>
10
10
  <%= form.url_field :example_url_field, props: { label: true, required: true, required_indicator: true } %>
11
11
  <%= form.phone_number_field :example_phone_number_field, props: { label: true, required: true, required_indicator: true } %>
12
+ <%= form.time_picker :example_time_picker_required_indicator, props: { label: true, required: true, required_indicator: true } %>
12
13
 
13
14
  <%= form.actions do |action| %>
14
15
  <%= action.submit %>
@@ -26,6 +26,10 @@ class PbFormValidation extends PbEnhancedElement {
26
26
  const isPhoneNumberInput = field.closest('.pb_phone_number_input')
27
27
  if (isPhoneNumberInput) return
28
28
 
29
+ // Skip TimePicker inputs - they handle their own validation
30
+ const isTimePickerInput = field.closest('.pb_time_picker')
31
+ if (isTimePickerInput) return
32
+
29
33
  FIELD_EVENTS.forEach((e) => {
30
34
  field.addEventListener(e, debounce((event) => {
31
35
  this.validateFormField(event)
@@ -67,13 +71,16 @@ class PbFormValidation extends PbEnhancedElement {
67
71
 
68
72
  // Check if this is a phone number input
69
73
  const isPhoneNumberInput = kitElement.classList.contains('pb_phone_number_input')
74
+
75
+ // Check if this is a TimePicker input
76
+ const isTimePickerInput = kitElement.classList.contains('pb_time_picker')
70
77
 
71
78
  // ensure clean error message state
72
79
  this.clearError(target)
73
80
  kitElement.classList.add('error')
74
81
 
75
- // Only add error message if it's NOT a phone number input
76
- if (!isPhoneNumberInput) {
82
+ // Only add error message if it's NOT a phone number input or TimePicker input
83
+ if (!isPhoneNumberInput && !isTimePickerInput) {
77
84
  // set the error message element
78
85
  const errorMessageContainer = this.errorMessageContainer
79
86
 
@@ -39,13 +39,6 @@
39
39
  display: flex;
40
40
  align-items: center;
41
41
  justify-content: space-between;
42
- @include transition_default;
43
-
44
- &:focus-within {
45
- border-color: $primary;
46
- background-color: $focus_input_light;
47
- }
48
-
49
42
  .input_inner_container {
50
43
  width: 100%;
51
44
  }