Building a Static DetailsList Component with Fluent UI in React

In this article, we will create a static DetailsList component using Fluent UI in a React application. This component will display a list of documents and allow users to filter the list by document name. We’ll learn how to pass an array of items as props and implement a text filter for enhanced user experience.

Prerequisites

Before we begin, ensure you have the following:

  • Basic knowledge of React and TypeScript.
  • A React application set up (you can use Create React App).
  • Fluent UI installed in your project. If you haven’t installed it yet, run:
npm install @fluentui/react

Step 1: Define the Document Interface

First, we need to define an interface for our document items. This interface will help TypeScript understand the structure of the items we’ll be working with.

export interface IDocument {
  key: string;
  name: string;
  modifiedBy: string;
  dateModified: string;
  fileSize: string;
}

Step 2: Create the DetailsList Component

Next, we’ll create our DetailsListStaticExample component. This component will accept an array of documents as props and include a text field for filtering.

import * as React from 'react';
import { TextField } from '@fluentui/react/lib/TextField';
import { DetailsList, DetailsListLayoutMode, IColumn, SelectionMode } from '@fluentui/react/lib/DetailsList';

export interface IDetailsListStaticExampleProps {
  items: IDocument[];
}

export interface IDetailsListStaticExampleState {
  filteredItems: IDocument[];
}

export class DetailsListStaticExample extends React.Component<IDetailsListStaticExampleProps, IDetailsListStaticExampleState> {
  constructor(props: IDetailsListStaticExampleProps) {
    super(props);
    this.state = {
      filteredItems: props.items, // Initialize with the props items
    };
  }

  public render() {
    const { filteredItems } = this.state;

    const columns: IColumn[] = [
      {
        key: 'column1',
        name: 'Name',
        fieldName: 'name',
        minWidth: 210,
        maxWidth: 350,
        isRowHeader: true,
        isResizable: true,
        isSorted: true,
        onRender: (item: IDocument) => <span>{item.name}</span>,
      },
      {
        key: 'column2',
        name: 'Modified By',
        fieldName: 'modifiedBy',
        minWidth: 70,
        maxWidth: 90,
        isResizable: true,
        onRender: (item: IDocument) => <span>{item.modifiedBy}</span>,
      },
      {
        key: 'column3',
        name: 'Date Modified',
        fieldName: 'dateModified',
        minWidth: 70,
        maxWidth: 90,
        isResizable: true,
        onRender: (item: IDocument) => <span>{item.dateModified}</span>,
      },
      {
        key: 'column4',
        name: 'File Size',
        fieldName: 'fileSize',
        minWidth: 70,
        maxWidth: 90,
        isResizable: true,
        onRender: (item: IDocument) => <span>{item.fileSize}</span>,
      },
    ];

    return (
      <div>
        <TextField
          label="Filter by name:"
          onChange={this._onChangeText}
          styles={{ root: { marginBottom: '20px' } }}
        />
        <DetailsList
          items={filteredItems}
          columns={columns}
          selectionMode={SelectionMode.none}
          setKey="none"
          layoutMode={DetailsListLayoutMode.justified}
          isHeaderVisible={true}
        />
      </div>
    );
  }

  private _onChangeText = (ev: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>, text: string): void => {
    const filteredItems = this.props.items.filter(item => 
      item.name.toLowerCase().includes(text.toLowerCase())
    );
    this.setState({ filteredItems });
  };
}

Key Features of the Component:

  1. Props: The component accepts an array of items (IDocument[]) as props.
  2. State Management: The component maintains a local state (filteredItems) to track the items displayed in the DetailsList.
  3. Columns Definition: We define the columns for our DetailsList, specifying how to render each item’s properties.
  4. Text Filtering: The component includes a TextField that allows users to filter the list based on the document name.

Step 3: Usage Example

Now that we have our component defined, let’s see how to use it in our application. We will pass an array of document items to the DetailsListStaticExample component.

import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { DetailsListStaticExample, IDocument } from './DetailsListStaticExample';

const documents: IDocument[] = [
  { key: '1', name: 'Document 1', modifiedBy: 'User 1', dateModified: '2024-11-01', fileSize: '10 KB' },
  { key: '2', name: 'Document 2', modifiedBy: 'User 2', dateModified: '2024-11-02', fileSize: '20 KB' },
  { key: '3', name: 'Document 3', modifiedBy: 'User 3', dateModified: '2024-11-03', fileSize: '30 KB' },
  { key: '4', name: 'Document 4', modifiedBy: 'User 4', dateModified: '2024-11-04', fileSize: '40 KB' },
  { key: '5', name: 'Document 5', modifiedBy: 'User 5', dateModified: '2024-11-05', fileSize: '50 KB' },
  // Add more documents as needed...
];

const App = () => {
  return (
    <div>
      <h1>Documents List</h1>
      <DetailsListStaticExample items={documents} />
    </div>
  );
};

ReactDOM.render(<App />, document.getElementById('root'));

Explanation of Usage:

  • Array of Documents: We create an array of documents adhering to the IDocument interface.
  • Rendering the Component: We render the DetailsListStaticExample component, passing the documents array as props.

Conclusion

In this article, we learned how to build a static DetailsList component in React using Fluent UI. We created a reusable component that accepts document items as props and provides a text filter for improved user interaction. This approach can be expanded and customized further to meet the specific needs of your applications.

Edvaldo Guimrães Filho Avatar

Published by

Categories: