Search code examples
typescriptprimereactprimeicons

How to change custom sort icons coming from primereact


I am trying to create a custom reusable data table component with primereact. Now I want to add sort functionality to my column.

I have added a function for sorting and for sorting I want to have my custom icons according to my requirement instead of having up arrow and down arrow from primereact. I have added

`const customSort = (field: string) => {
    setSortField(field);
    setSortOrder(sortOrder === 1 ? -1 : 1);
  };

  const sortedData = [...dataToDisplay].sort((a, b) => {
    if (sortField) {
      const compareValueA = a[sortField];
      const compareValueB = b[sortField];
      if (compareValueA < compareValueB) {
        return sortOrder;
      }
      if (compareValueA > compareValueB) {
        return -sortOrder;
      }
    }
    return 0;
  });`

this simple sort logic and tried to implement my custom icons instead of prmereact sort icons as

`<Column
            key={index}
            field={column.field}
            header={
              <div
                className={`custom-header-${sortField === column.field ? (sortOrder === 1 ? 'up' : 'down') : ''}`}
                onClick={() => customSort(column.field)}
              >
                {column.header}
                {column.field === sortField && (
                  <i className={`pi pi-angle-${sortOrder === 1 ? 'up' : 'down'}`} />
                )}
              </div>
            }
            sortable
          />
        ))}`

But still sort icons from prime react are coming. Can someone please help me with this. Thanks in advance.


Solution

  • I found the solution myself. Here is what I did:

    renderSortButtons = (field: string) => {
      return (
        <div className="sort-buttons">
          <button onClick={() => this.props.onSortChange(field, 1)}>
            <UpArrow />
          </button>
          <button onClick={() => this.props.onSortChange(field, -1)}>
            <DownArrow  />
          </button>
        </div>
      );
    };
    

    I added a function called enderSortbuttons and handled the sorting:

    {React.Children.map(this.props.children, (child: ReactNode) => {
      if (React.isValidElement<ColumnProps>(child)) {
        return React.cloneElement(child as React.ReactElement<ColumnProps>, {
          header: (
            <>
              {child.props.header}{' '}
              {child.props.sortable && this.renderSortButtons(child.props.field || '')}
            </>
          ),
        });
      }
      return null;
    })}
    

    I made my header to have this if I pass sortable in the Column component. Initially I even have primereact icons for sorting. But then I used CSS to hide them.