logo
Published on

PnP ListItem Attachments Control in the SharePoint Framework (SPFx) Web Part

This article demonstrates how to implement the PnP ListItem Attachments Control in a SharePoint Framework (SPFx) web part.
It allows you to view, add, and delete attachments associated with list items directly within the SharePoint interface.


⚙️ Install Required Dependencies

npm install @pnp/spfx-controls-react --save --save-exact

This installs the PnP Reusable SPFx Controls, including ListItemAttachmentsControl.


🧩 Define Component State

Create a file named ISpfxPnpListitemattachmentsState.ts under the components folder:

export interface ISpfxPnpListitemattachmentsState {
  SelectedList: string;
  SelectedItem: number;
}

⚛️ Implement the List Item Attachment Control

Create or update your main React component SpfxPnpListitemattachments.tsx as follows:

import * as React from 'react';
import styles from './SpfxPnpListitemattachments.module.scss';
import { ISpfxPnpListitemattachmentsProps } from './ISpfxPnpListitemattachmentsProps';
import { ISpfxPnpListitemattachmentsState } from './ISpfxPnpListitemattachmentsState';
import { ListPicker } from '@pnp/spfx-controls-react/lib/ListPicker';
import { ListItemPicker } from '@pnp/spfx-controls-react/lib/ListItemPicker';
import { Label } from 'office-ui-fabric-react/lib/Label';
import { sp } from '@pnp/sp/presets/all';
import { autobind } from 'office-ui-fabric-react/lib/Utilities';
import { PnPListItemAttachments } from './PnPListItemAttachments';

export default class SpfxPnpListitemattachments extends React.Component<ISpfxPnpListitemattachmentsProps, ISpfxPnpListitemattachmentsState> {
  constructor(props: ISpfxPnpListitemattachmentsProps) {
    super(props);
    this.state = { SelectedList: '', SelectedItem: null };
  }

  public render(): React.ReactElement<ISpfxPnpListitemattachmentsProps> {
    return (
      <div className={styles.spfxPnpListitemattachments}>
        <Label>Select SharePoint List</Label>
        <ListPicker
          context={this.props.context}
          placeholder="Select your list"
          baseTemplate={100}
          includeHidden={false}
          multiSelect={false}
          onSelectionChanged={this.onListPickerChange}
        />
        <br />
        <Label>Select Item</Label>
        <ListItemPicker
          listId={this.state.SelectedList}
          context={this.props.context}
          keyColumnInternalName="ID"
          keyColumnTitle="Title"
          onSelectedItem={this.onItemPickerChange}
          webUrl={this.props.context.pageContext.web.absoluteUrl}
        />
        <br />
        <PnPListItemAttachments
          listId={this.state.SelectedList}
          itemId={this.state.SelectedItem}
          context={this.props.context}
        />
      </div>
    );
  }

  @autobind
  private onListPickerChange(selectedListId: string): void {
    this.setState({ SelectedList: selectedListId, SelectedItem: null });
  }

  @autobind
  private onItemPickerChange(items: any[]): void {
    if (items.length > 0) {
      this.setState({ SelectedItem: items[0].Id });
    }
  }
}

🧱 Create a Separate Component for Attachments

Add a new component file named PnPListItemAttachments.tsx:

import * as React from 'react';
import { ListItemAttachments } from '@pnp/spfx-controls-react/lib/ListItemAttachments';
import styles from './PnPListItemAttachments.module.scss';

export interface IPnPListItemAttachmentsProps {
  context: any;
  listId: string;
  itemId: number;
}

export const PnPListItemAttachments: React.FC<IPnPListItemAttachmentsProps> = ({ context, listId, itemId }) => {
  if (!listId || !itemId) {
    return <div>Please select a list and item first.</div>;
  }

  return (
    <div className={styles.pnpListItemAttachments}>
      <ListItemAttachments
        listId={listId}
        itemId={itemId}
        context={context}
        disableAdd={false}
        disableDelete={false}
      />
    </div>
  );
};

💡 Explanation

  • ListPicker dynamically loads SharePoint lists.
  • ListItemPicker lets you select an item from the selected list.
  • ListItemAttachments displays, uploads, and deletes attachments.
  • All actions happen dynamically without reloading the page.

🧠 Example Output

Once deployed, you can select a list, choose a list item, and manage its attachments directly from the web part interface — including adding, deleting, and downloading files.


🚀 Deploy the Solution

Run the following commands to build and deploy:

gulp build
gulp bundle --ship
gulp package-solution --ship

Upload the .sppkg file to your App Catalog and deploy the solution.


📂 GitHub Source

View full SPFx project on GitHub:PnP ListItem Attachments Control in SPFx

GitHub

✅ Summary

This solution demonstrates how to use PnP Reusable Controls to manage attachments efficiently within an SPFx web part — allowing users to view, upload, and remove attachments with ease.

Calendar IconBook a demo