Skip to content

Commit

Permalink
[PBNTR-381] Implementing form resetting and blank selection prop (#3529)
Browse files Browse the repository at this point in the history
**What does this PR do?**
 Implementing form resetting and blank selection prop.

**Screenshots:**

![image](https://github.com/user-attachments/assets/3df9eb1b-248d-4589-9989-c19e05079390)

**How to test?**
1. Go to the Dropdown kit page.
2. Scroll down to "Blank Selection" doc example (last one)

#### Checklist:
- [x] **LABELS** Add a label: `enhancement`, `bug`, `improvement`, `new
kit`, `deprecated`, or `breaking`. See [Changelog &
Labels](https://github.com/powerhome/playbook/wiki/Changelog-&-Labels)
for details.
- [x] **DEPLOY** I have added the `milano` label to show I'm ready for a
review.
- [ ] **TESTS** I have added test coverage to my code.
  • Loading branch information
carloslimasd authored Jul 18, 2024
1 parent 54143ff commit 192080e
Show file tree
Hide file tree
Showing 9 changed files with 96 additions and 17 deletions.
15 changes: 9 additions & 6 deletions playbook/app/pb_kits/playbook/pb_dropdown/_dropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
type DropdownProps = {
aria?: { [key: string]: string };
autocomplete?: boolean;
blankSelection?: string;
children?: React.ReactChild[] | React.ReactChild | React.ReactElement[];
className?: string;
dark?: boolean;
Expand All @@ -41,6 +42,7 @@ const Dropdown = (props: DropdownProps) => {
const {
aria = {},
autocomplete = false,
blankSelection = '',
children,
className,
dark = false,
Expand Down Expand Up @@ -118,11 +120,12 @@ const Dropdown = (props: DropdownProps) => {
setIsDropDownClosed(isClosed)
}, [isClosed])

const filteredOptions = options?.filter((option: GenericObject) => {
const blankSelectionOption: GenericObject = blankSelection ? [{ label: blankSelection, value: "" }] : [];
const optionsWithBlankSelection = blankSelectionOption.concat(options);
const filteredOptions = optionsWithBlankSelection?.filter((option: GenericObject) => {
const label = typeof option.label === 'string' ? option.label.toLowerCase() : option.label;
return String(label).toLowerCase().includes(filterItem.toLowerCase());
}
);
});

// For keyboard accessibility: Set focus within dropdown to selected item if it exists
useEffect(() => {
Expand Down Expand Up @@ -196,7 +199,7 @@ const Dropdown = (props: DropdownProps) => {
inputWrapperRef,
isDropDownClosed,
isInputFocused,
options,
optionsWithBlankSelection,
selected,
setFocusedOptionIndex,
setIsDropDownClosed,
Expand Down Expand Up @@ -235,8 +238,8 @@ const Dropdown = (props: DropdownProps) => {
<>
<DropdownTrigger />
<DropdownContainer>
{options &&
options?.map((option: GenericObject) => (
{optionsWithBlankSelection &&
optionsWithBlankSelection?.map((option: GenericObject) => (
<Dropdown.Option key={option.id}
option={option}
/>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<%
options = [
{ label: 'United States', value: 'United States', id: 'us' },
{ label: 'Canada', value: 'Canada', id: 'ca' },
{ label: 'Pakistan', value: 'Pakistan', id: 'pk' },
]

%>

<%= pb_rails("dropdown", props: { blank_selection: "Select One...", options: options }) %>
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import React from 'react'
import { Dropdown } from '../../'

const DropdownBlankSelection = (props) => {
const options = [
{
label: "United States",
value: "United States",
},
{
label: "Canada",
value: "Canada",
},
{
label: "Pakistan",
value: "Pakistan",
}
];

return (
<>
<Dropdown
blankSelection="Select one..."
options={options}
{...props}
/>
</>
)
}

export default DropdownBlankSelection
2 changes: 2 additions & 0 deletions playbook/app/pb_kits/playbook/pb_dropdown/docs/example.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ examples:
- dropdown_with_custom_padding: Custom Option Padding
- dropdown_error: Dropdown with Error
- dropdown_default_value: Default Value
- dropdown_blank_selection: Blank Selection

react:
- dropdown_default: Default
Expand All @@ -20,6 +21,7 @@ examples:
- dropdown_with_custom_padding: Custom Option Padding
- dropdown_error: Dropdown with Error
- dropdown_default_value: Default Value
- dropdown_blank_selection: Blank Selection
# - dropdown_with_autocomplete: Autocomplete
# - dropdown_with_autocomplete_and_custom_display: Autocomplete with Custom Display
# - dropdown_with_external_control: useDropdown Hook
Expand Down
3 changes: 2 additions & 1 deletion playbook/app/pb_kits/playbook/pb_dropdown/docs/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ export { default as DropdownWithExternalControl } from './_dropdown_with_externa
export { default as DropdownWithHook } from './_dropdown_with_hook.jsx'
export { default as DropdownSubcomponentStructure } from './_dropdown_subcomponent_structure.jsx'
export { default as DropdownError } from './_dropdown_error.jsx'
export { default as DropdownDefaultValue } from './_dropdown_default_value.jsx'
export { default as DropdownDefaultValue } from './_dropdown_default_value.jsx'
export { default as DropdownBlankSelection } from './_dropdown_blank_selection.jsx'
4 changes: 2 additions & 2 deletions playbook/app/pb_kits/playbook/pb_dropdown/dropdown.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
<% else %>
<%= pb_rails("dropdown/dropdown_trigger") %>
<%= pb_rails("dropdown/dropdown_container") do %>
<% if object.options.present? %>
<% object.options.each do |option| %>
<% if options_with_blank.present? %>
<% options_with_blank.each do |option| %>
<%= pb_rails("dropdown/dropdown_option", props: {option: option}) %>
<% end %>
<% end %>
Expand Down
6 changes: 6 additions & 0 deletions playbook/app/pb_kits/playbook/pb_dropdown/dropdown.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ class Dropdown < Playbook::KitBase
prop :required, type: Playbook::Props::Boolean,
default: false
prop :default_value
prop :blank_selection, type: Playbook::Props::String,
default: ""

def data
Hash(prop(:data)).merge(pb_dropdown: true)
Expand All @@ -29,6 +31,10 @@ def error_class
def input_default_value
default_value.present? ? default_value.transform_keys(&:to_s) : ""
end

def options_with_blank
blank_selection.present? ? [{ id: "", value: "", label: blank_selection }] + options : options
end
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class DropdownTrigger < Playbook::KitBase
prop :custom_display

def data
Hash(prop(:data)).merge(dropdown_trigger: true)
Hash(prop(:data)).merge(dropdown_trigger: true, dropdown_placeholder: default_display_placeholder)
end

def classname
Expand Down
40 changes: 33 additions & 7 deletions playbook/app/pb_kits/playbook/pb_dropdown/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ const UP_ARROW_SELECTOR = "#dropdown_close_icon";
const OPTION_SELECTOR = "[data-dropdown-option-label]";
const CUSTOM_DISPLAY_SELECTOR = "[data-dropdown-custom-trigger]";
const INPUT_FORM_VALIDATION = "#dropdown-form-validation";
const DROPDOWN_TRIGGER_DISPLAY = "#dropdown_trigger_display";
const DROPDOWN_PLACEHOLDER = "[data-dropdown-placeholder]";

export default class PbDropdown extends PbEnhancedElement {
static get selector() {
Expand All @@ -25,6 +27,7 @@ export default class PbDropdown extends PbEnhancedElement {
this.bindEventListeners();
this.updateArrowDisplay(false);
this.handleFormValidation();
this.handleFormReset();
}

bindEventListeners() {
Expand Down Expand Up @@ -84,9 +87,7 @@ export default class PbDropdown extends PbEnhancedElement {
}

onOptionSelected(value, selectedOption) {
const triggerElement = this.element.querySelector(
"#dropdown_trigger_display"
);
const triggerElement = this.element.querySelector(DROPDOWN_TRIGGER_DISPLAY);
const customDisplayElement = this.element.querySelector(
"#dropdown_trigger_custom_display"
);
Expand Down Expand Up @@ -195,13 +196,38 @@ export default class PbDropdown extends PbEnhancedElement {
}
});

const triggerElement = this.element.querySelector("#dropdown_trigger_display");
if (triggerElement) {
triggerElement.textContent = defaultValue.label;
}
this.setTriggerElementText(defaultValue.label);

hiddenInput.value = defaultValue.id;
inputFormValidation.value = defaultValue.id;
}
}

handleFormReset() {
const form = this.element.closest("form");

if (form) {
form.addEventListener("reset", () => {
this.resetDropdownValue();
});
}
}

resetDropdownValue() {
const hiddenInput = this.element.querySelector("#dropdown-selected-option");
const inputFormValidation = this.element.querySelector(INPUT_FORM_VALIDATION);

hiddenInput.value = "";
inputFormValidation.value = "";

const defaultPlaceholder = this.element.querySelector(DROPDOWN_PLACEHOLDER);
this.setTriggerElementText(defaultPlaceholder.dataset.dropdownPlaceholder);
}

setTriggerElementText(text) {
const triggerElement = this.element.querySelector(DROPDOWN_TRIGGER_DISPLAY);
if (triggerElement) {
triggerElement.textContent = text;
}
}
}

0 comments on commit 192080e

Please sign in to comment.