diff --git a/components/doc/treeselect/clearicondoc.js b/components/doc/treeselect/clearicondoc.js
new file mode 100644
index 0000000000..0d9b51f97d
--- /dev/null
+++ b/components/doc/treeselect/clearicondoc.js
@@ -0,0 +1,107 @@
+import React, { useEffect, useState } from 'react';
+import { NodeService } from '../../../service/NodeService';
+import { TreeSelect } from '../../lib/treeselect/TreeSelect';
+import { DocSectionCode } from '../common/docsectioncode';
+import { DocSectionText } from '../common/docsectiontext';
+
+export function ClearIconDoc(props) {
+ const [nodes, setNodes] = useState(null);
+ const [selectedNodeKey, setSelectedNodeKey] = useState(null);
+
+ useEffect(() => {
+ NodeService.getTreeNodes().then((data) => setNodes(data));
+ }, []); // eslint-disable-line react-hooks/exhaustive-deps
+
+ const code = {
+ basic: `
+ setSelectedNodeKey(e.value)} options={nodes}
+ className="md:w-20rem w-full" placeholder="Select Item">
+ `,
+ javascript: `
+import React, { useState, useEffect } from "react";
+import { TreeSelect } from 'primereact/treeselect';
+import { NodeService } from './service/NodeService';
+
+export default function BasicDemo() {
+ const [nodes, setNodes] = useState(null);
+ const [selectedNodeKey, setSelectedNodeKey] = useState(null);
+
+ useEffect(() => {
+ NodeService.getTreeNodes().then((data) => setNodes(data));
+ }, []);
+
+ return (
+
+ setSelectedNodeKey(e.value)} options={nodes}
+ className="md:w-20rem w-full" placeholder="Select Item" showClear>
+
+ );
+}
+ `,
+ typescript: `
+import React, { useState, useEffect } from "react";
+import { TreeSelect, TreeSelectChangeEvent } from 'primereact/treeselect';
+import { TreeNode } from 'primereact/treenode';
+import { NodeService } from './service/NodeService';
+
+export default function BasicDemo() {
+ const [nodes, setNodes] = useState(null);
+ const [selectedNodeKey, setSelectedNodeKey] = useState(null);
+
+ useEffect(() => {
+ NodeService.getTreeNodes().then((data) => setNodes(data));
+ }, []);
+
+ return (
+
+ setSelectedNodeKey(e.value)}
+ className="md:w-20rem w-full" placeholder="Select Item" showClear>
+
+ );
+}
+ `,
+ data: `
+/* NodeService */
+{
+ key: '0',
+ label: 'Documents',
+ data: 'Documents Folder',
+ icon: 'pi pi-fw pi-inbox',
+ children: [
+ {
+ key: '0-0',
+ label: 'Work',
+ data: 'Work Folder',
+ icon: 'pi pi-fw pi-cog',
+ children: [
+ { key: '0-0-0', label: 'Expenses.doc', icon: 'pi pi-fw pi-file', data: 'Expenses Document' },
+ { key: '0-0-1', label: 'Resume.doc', icon: 'pi pi-fw pi-file', data: 'Resume Document' }
+ ]
+ },
+ {
+ key: '0-1',
+ label: 'Home',
+ data: 'Home Folder',
+ icon: 'pi pi-fw pi-home',
+ children: [{ key: '0-1-0', label: 'Invoices.txt', icon: 'pi pi-fw pi-file', data: 'Invoices for this month' }]
+ }
+ ]
+},
+...
+`
+ };
+
+ return (
+ <>
+
+
+ When showClear is enabled, a clear icon is added to reset the TreeSelect.
+
+
+
+ setSelectedNodeKey(e.value)} options={nodes} className="md:w-20rem w-full" placeholder="Select Item" showClear>
+
+
+ >
+ );
+}
diff --git a/components/lib/dropdown/Dropdown.js b/components/lib/dropdown/Dropdown.js
index b265bc1b99..3c225863aa 100644
--- a/components/lib/dropdown/Dropdown.js
+++ b/components/lib/dropdown/Dropdown.js
@@ -1,6 +1,6 @@
import * as React from 'react';
-import PrimeReact, { FilterService } from '../api/Api';
-import { PrimeReactContext } from '../api/Api';
+import PrimeReact, { FilterService, PrimeReactContext } from '../api/Api';
+import { useHandleStyle } from '../componentbase/ComponentBase';
import { useMountEffect, useOverlayListener, useUnmountEffect, useUpdateEffect } from '../hooks/Hooks';
import { ChevronDownIcon } from '../icons/chevrondown';
import { TimesIcon } from '../icons/times';
@@ -9,7 +9,6 @@ import { Tooltip } from '../tooltip/Tooltip';
import { DomHandler, IconUtils, ObjectUtils, ZIndexUtils, mergeProps } from '../utils/Utils';
import { DropdownBase } from './DropdownBase';
import { DropdownPanel } from './DropdownPanel';
-import { useHandleStyle } from '../componentbase/ComponentBase';
export const Dropdown = React.memo(
React.forwardRef((inProps, ref) => {
@@ -624,6 +623,7 @@ export const Dropdown = React.memo(
props,
show,
hide,
+ clear,
focus: () => DomHandler.focus(focusInputRef.current),
getElement: () => elementRef.current,
getOverlay: () => overlayRef.current,
diff --git a/components/lib/dropdown/DropdownBase.js b/components/lib/dropdown/DropdownBase.js
index ae3a84a28f..2bb561227a 100644
--- a/components/lib/dropdown/DropdownBase.js
+++ b/components/lib/dropdown/DropdownBase.js
@@ -23,7 +23,6 @@ const classes = {
'p-dropdown-label-empty': label === null && !props.placeholder
}),
trigger: 'p-dropdown-trigger',
- clearIcon: 'p-dropdown-clear-icon p-clickable',
emptyMessage: 'p-dropdown-empty-message',
itemGroup: 'p-dropdown-item-group',
dropdownIcon: 'p-dropdown-trigger-icon p-clickable',
@@ -60,12 +59,6 @@ const styles = `
user-select: none;
}
-.p-dropdown-clear-icon {
- position: absolute;
- top: 50%;
- margin-top: -.5rem;
-}
-
.p-dropdown-trigger {
display: flex;
align-items: center;
@@ -128,6 +121,7 @@ input.p-dropdown-label {
position: relative;
}
+.p-dropdown-clear-icon,
.p-dropdown-filter-icon,
.p-dropdown-filter-clear-icon {
position: absolute;
diff --git a/components/lib/dropdown/dropdown.d.ts b/components/lib/dropdown/dropdown.d.ts
index 5c70430b8c..a6083f7698 100644
--- a/components/lib/dropdown/dropdown.d.ts
+++ b/components/lib/dropdown/dropdown.d.ts
@@ -508,6 +508,18 @@ export declare class Dropdown extends React.Component {
* Used to focus the component.
*/
public focus(): void;
+ /**
+ * Clear the currently selected value.
+ */
+ public clear(): void;
+ /**
+ * Show the dropdown overlay panel.
+ */
+ public show(): void;
+ /**
+ * Hide the dropdown overlay panel.
+ */
+ public hide(): void;
/**
* Used to get container element.
* @return {HTMLDivElement} Container element
diff --git a/components/lib/treeselect/TreeSelect.js b/components/lib/treeselect/TreeSelect.js
index ff6ab9854f..fcac6b4ee0 100644
--- a/components/lib/treeselect/TreeSelect.js
+++ b/components/lib/treeselect/TreeSelect.js
@@ -1,6 +1,6 @@
import * as React from 'react';
-import PrimeReact, { localeOption } from '../api/Api';
-import { PrimeReactContext } from '../api/Api';
+import PrimeReact, { PrimeReactContext, localeOption } from '../api/Api';
+import { useHandleStyle } from '../componentbase/ComponentBase';
import { useMountEffect, useOverlayListener, useUnmountEffect, useUpdateEffect } from '../hooks/Hooks';
import { ChevronDownIcon } from '../icons/chevrondown';
import { SearchIcon } from '../icons/search';
@@ -8,10 +8,9 @@ import { TimesIcon } from '../icons/times';
import { OverlayService } from '../overlayservice/OverlayService';
import { Ripple } from '../ripple/Ripple';
import { Tree } from '../tree/Tree';
-import { DomHandler, IconUtils, ObjectUtils, ZIndexUtils, classNames, mergeProps } from '../utils/Utils';
+import { DomHandler, IconUtils, ObjectUtils, ZIndexUtils, mergeProps } from '../utils/Utils';
import { TreeSelectBase } from './TreeSelectBase';
import { TreeSelectPanel } from './TreeSelectPanel';
-import { useHandleStyle } from '../componentbase/ComponentBase';
export const TreeSelect = React.memo(
React.forwardRef((inProps, ref) => {
@@ -110,6 +109,28 @@ export const TreeSelect = React.memo(
}
};
+ const clear = (event) => {
+ if (props.onChange) {
+ selfChange.current = true;
+
+ props.onChange({
+ originalEvent: event,
+ value: undefined,
+ stopPropagation: () => {
+ event.stopPropagation();
+ },
+ preventDefault: () => {
+ event.preventDefault();
+ },
+ target: {
+ name: props.name,
+ id: props.id,
+ value: undefined
+ }
+ });
+ }
+ };
+
const onNodeSelect = (node) => {
props.onNodeSelect && props.onNodeSelect(node);
isSingleSelectionMode && hide();
@@ -323,6 +344,9 @@ export const TreeSelect = React.memo(
React.useImperativeHandle(ref, () => ({
props,
+ clear,
+ show,
+ hide,
focus: () => DomHandler.focus(focusInputRef.current),
getElement: () => elementRef.current
}));
@@ -485,6 +509,23 @@ export const TreeSelect = React.memo(
return {dropdownIcon}
;
};
+ const createClearIcon = () => {
+ if (props.value != null && props.showClear && !props.disabled) {
+ const clearIconProps = mergeProps(
+ {
+ className: cx('clearIcon'),
+ onPointerUp: clear
+ },
+ ptm('clearIcon')
+ );
+ const icon = props.clearIcon || ;
+
+ return IconUtils.getJSXIcon(icon, { ...clearIconProps }, { props });
+ }
+
+ return null;
+ };
+
const createContent = () => {
const emptyMessageProps = mergeProps(
{
@@ -665,6 +706,7 @@ export const TreeSelect = React.memo(
const keyboardHelper = createKeyboardHelper();
const labelElement = createLabel();
const dropdownIcon = createDropdownIcon();
+ const clearIcon = createClearIcon();
const content = createContent();
const header = createHeader();
const footer = createFooter();
@@ -673,6 +715,7 @@ export const TreeSelect = React.memo(
{keyboardHelper}
{labelElement}
+ {clearIcon}
{dropdownIcon}
| React.HTMLAttributes>;
+ /**
+ * uses to pass attributes to the clear icon's DOM element.
+ */
+ clearIcon?: TreeSelectPassThroughType | React.HTMLAttributes>;
}
/**
@@ -303,6 +307,10 @@ export interface TreeSelectProps extends Omit | undefined;
/**
* Icon of the close button.
*/
@@ -439,6 +447,11 @@ export interface TreeSelectProps extends Omit {
* Used to focus the component.
*/
public focus(): void;
+ /**
+ * Clear the currently selected value.
+ */
+ public clear(): void;
+ /**
+ * Show the dropdown overlay panel.
+ */
+ public show(): void;
+ /**
+ * Hide the dropdown overlay panel.
+ */
+ public hide(): void;
/**
* Used to get container element.
* @return {HTMLDivElement} Container element
diff --git a/pages/treeselect/index.js b/pages/treeselect/index.js
index de6d283f6e..d3602b42a7 100644
--- a/pages/treeselect/index.js
+++ b/pages/treeselect/index.js
@@ -1,10 +1,10 @@
import DocApiTable from '../../components/doc/common/docapitable';
-import { PTDoc } from '../../components/doc/treeselect/pt/ptdoc';
-import { Wireframe } from '../../components/doc/treeselect/pt/wireframe';
import { DocComponent } from '../../components/doc/common/doccomponent';
import { AccessibilityDoc } from '../../components/doc/treeselect/accessibilitydoc';
import { BasicDoc } from '../../components/doc/treeselect/basicdoc';
import { CheckboxDoc } from '../../components/doc/treeselect/checkboxdoc';
+import { ClearIconDoc } from '../../components/doc/treeselect/clearicondoc';
+import { ControlledDoc } from '../../components/doc/treeselect/controlleddoc';
import { DisabledDoc } from '../../components/doc/treeselect/disableddoc';
import { FilterDoc } from '../../components/doc/treeselect/filterdoc';
import { FloatLabelDoc } from '../../components/doc/treeselect/floatlabeldoc';
@@ -13,7 +13,8 @@ import { HookFormDoc } from '../../components/doc/treeselect/form/hookformdoc';
import { ImportDoc } from '../../components/doc/treeselect/importdoc';
import { InvalidDoc } from '../../components/doc/treeselect/invaliddoc';
import { MultipleDoc } from '../../components/doc/treeselect/multipledoc';
-import { ControlledDoc } from '../../components/doc/treeselect/controlleddoc';
+import { PTDoc } from '../../components/doc/treeselect/pt/ptdoc';
+import { Wireframe } from '../../components/doc/treeselect/pt/wireframe';
import { StyleDoc } from '../../components/doc/treeselect/styledoc';
const TreeSelectDemo = () => {
@@ -43,6 +44,11 @@ const TreeSelectDemo = () => {
label: 'Filter',
component: FilterDoc
},
+ {
+ id: 'clearicon',
+ label: 'Clear Icon',
+ component: ClearIconDoc
+ },
{
id: 'controlled',
label: 'Controlled',