Skip to content

Commit

Permalink
[PBNTR-568] Adding React Dropdown cleaning feature (#3793)
Browse files Browse the repository at this point in the history
**What does this PR do?**
Adding React Dropdown cleaning feature

**Screenshots:**
<img width="883" alt="image"
src="https://github.com/user-attachments/assets/b1080c00-9299-46ac-a481-196ca05026ff">

**How to test?**
1. Go to the Dropdown kit page
2. Scroll down to the Clear Selection doc

#### 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 Oct 17, 2024
1 parent 88302fb commit 86b841a
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 7 deletions.
24 changes: 20 additions & 4 deletions playbook/app/pb_kits/playbook/pb_dropdown/_dropdown.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState, useRef, useEffect } from "react";
import React, { useState, useRef, useEffect, forwardRef, useImperativeHandle } from "react";
import classnames from "classnames";
import { buildAriaProps, buildCss, buildDataProps, buildHtmlProps } from "../utilities/props";
import { globalProps } from "../utilities/globalProps";
Expand Down Expand Up @@ -38,7 +38,14 @@ type DropdownProps = {
triggerRef?: any;
};

const Dropdown = (props: DropdownProps) => {
interface DropdownComponent
extends React.ForwardRefExoticComponent<DropdownProps & React.RefAttributes<unknown>> {
Option: typeof DropdownOption;
Trigger: typeof DropdownTrigger;
Container: typeof DropdownContainer;
}

const Dropdown = forwardRef((props: DropdownProps, ref: any) => {
const {
aria = {},
autocomplete = false,
Expand Down Expand Up @@ -125,7 +132,7 @@ const Dropdown = (props: DropdownProps) => {
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 @@ -175,6 +182,14 @@ const Dropdown = (props: DropdownProps) => {
dark
});

useImperativeHandle(ref, () => ({
clearSelected: () => {
setSelected({});
setFilterItem("");
setIsDropDownClosed(true);
onSelect && onSelect(null);
},
}));

return (
<div {...ariaProps}
Expand Down Expand Up @@ -258,8 +273,9 @@ const Dropdown = (props: DropdownProps) => {
</DropdownContext.Provider>
</div>
)
};
}) as DropdownComponent

Dropdown.displayName = "Dropdown";
Dropdown.Option = DropdownOption;
Dropdown.Trigger = DropdownTrigger;
Dropdown.Container = DropdownContainer;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import React, { useRef } from 'react'
import { Button, Dropdown } from 'playbook-ui'

const options = [
{
label: "United States",
value: "United States",
},
{
label: "Canada",
value: "Canada",
},
{
label: "Pakistan",
value: "Pakistan",
}
]

const DropdownClearSelection = (props) => {
const dropdownRef = useRef(null)

const handleReset = () => {
if (dropdownRef.current) {
dropdownRef.current.clearSelected()
}
}

return (
<>
<Dropdown
defaultValue={options[2]}
options={options}
ref={dropdownRef}
{...props}
/>
<Button
marginTop="md"
onClick={handleReset}
text="Reset"
/>
</>
)
}

export default DropdownClearSelection
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
To use an external control (like a reset button) to clear Dropdown selection, you can make use of the `useRef` hook. You must pass a ref to the Dropdown component and use that ref within the onClick for the external control in the way shown in the code snippet below.
1 change: 1 addition & 0 deletions playbook/app/pb_kits/playbook/pb_dropdown/docs/example.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ examples:
- dropdown_error: Dropdown with Error
- dropdown_default_value: Default Value
- dropdown_blank_selection: Blank Selection
- dropdown_clear_selection: Clear Selection
# - dropdown_with_autocomplete: Autocomplete
# - dropdown_with_autocomplete_and_custom_display: Autocomplete with Custom Display
# - dropdown_with_external_control: useDropdown Hook
Expand Down
1 change: 1 addition & 0 deletions playbook/app/pb_kits/playbook/pb_dropdown/docs/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ export { default as DropdownSubcomponentStructure } from './_dropdown_subcompone
export { default as DropdownError } from './_dropdown_error.jsx'
export { default as DropdownDefaultValue } from './_dropdown_default_value.jsx'
export { default as DropdownBlankSelection } from './_dropdown_blank_selection.jsx'
export { default as DropdownClearSelection } from './_dropdown_clear_selection.jsx'
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ const DropdownOption = (props: DropdownOptionProps) => {
const focusedClass = isFocused && "focused";

const selectedClass = `${
selected.label === option.label
selected?.label === option.label
? "selected"
: "list"
}`;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ const DropdownTrigger = (props: DropdownTriggerProps) => {
!autocomplete && "select_only"
);

const customDisplayPlaceholder = selected.label ? (
const customDisplayPlaceholder = selected?.label ? (
<b>{selected.label}</b>
) : autocomplete ? (
""
Expand All @@ -83,7 +83,7 @@ const DropdownTrigger = (props: DropdownTriggerProps) => {
"Select..."
);

const defaultDisplayPlaceholder = selected.label
const defaultDisplayPlaceholder = selected?.label
? selected.label
: autocomplete
? ""
Expand Down

0 comments on commit 86b841a

Please sign in to comment.