diff --git a/ash/picker/model/picker_model.cc b/ash/picker/model/picker_model.cc
index 6ff429a756b8a..6ed175bf149ac 100644
--- a/ash/picker/model/picker_model.cc
+++ b/ash/picker/model/picker_model.cc
@@ -67,6 +67,18 @@ std::vector<PickerCategory> PickerModel::GetAvailableCategories() const {
   return categories;
 }
 
+std::vector<PickerCategory> PickerModel::GetRecentResultsCategories() const {
+  if (HasSelectedText()) {
+    return std::vector<PickerCategory>{};
+  }
+
+  return {
+      PickerCategory::kDriveFiles,
+      PickerCategory::kLocalFiles,
+      PickerCategory::kLinks,
+  };
+}
+
 bool PickerModel::HasSelectedText() const {
   return !selected_text_.empty();
 }
diff --git a/ash/picker/model/picker_model.h b/ash/picker/model/picker_model.h
index 33847b49be239..423a09b5eec43 100644
--- a/ash/picker/model/picker_model.h
+++ b/ash/picker/model/picker_model.h
@@ -33,6 +33,8 @@ class ASH_EXPORT PickerModel {
 
   std::vector<PickerCategory> GetAvailableCategories() const;
 
+  std::vector<PickerCategory> GetRecentResultsCategories() const;
+
   std::u16string_view selected_text() const;
 
   bool HasSelectedText() const;
diff --git a/ash/picker/picker_controller.cc b/ash/picker/picker_controller.cc
index 33f3e740449bb..e3a1ce0c35eee 100644
--- a/ash/picker/picker_controller.cc
+++ b/ash/picker/picker_controller.cc
@@ -361,8 +361,9 @@ std::vector<PickerCategory> PickerController::GetAvailableCategories() {
                            : model_->GetAvailableCategories();
 }
 
-bool PickerController::ShouldShowRecentResults() {
-  return model_ && !model_->HasSelectedText();
+std::vector<PickerCategory> PickerController::GetRecentResultsCategories() {
+  return model_ == nullptr ? std::vector<PickerCategory>{}
+                           : model_->GetRecentResultsCategories();
 }
 
 void PickerController::GetResultsForCategory(PickerCategory category,
diff --git a/ash/picker/picker_controller.h b/ash/picker/picker_controller.h
index e811d92eaffb7..7c59c74cc4048 100644
--- a/ash/picker/picker_controller.h
+++ b/ash/picker/picker_controller.h
@@ -75,7 +75,7 @@ class ASH_EXPORT PickerController
 
   // PickerViewDelegate:
   std::vector<PickerCategory> GetAvailableCategories() override;
-  bool ShouldShowRecentResults() override;
+  std::vector<PickerCategory> GetRecentResultsCategories() override;
   void GetResultsForCategory(PickerCategory category,
                              SearchResultsCallback callback) override;
   void TransformSelectedText(PickerCategory category) override;
diff --git a/ash/picker/views/picker_view.cc b/ash/picker/views/picker_view.cc
index fb166fecd61c6..a457616686b93 100644
--- a/ash/picker/views/picker_view.cc
+++ b/ash/picker/views/picker_view.cc
@@ -146,6 +146,19 @@ PickerCategory GetCategoryForMoreResults(PickerSectionType type) {
   }
 }
 
+std::vector<PickerSearchResult> GetMostRecentResult(
+    std::vector<PickerSearchResultsSection> results) {
+  if (results.empty() ||
+      results[0].type() != PickerSectionType::kRecentlyUsed) {
+    return {};
+  }
+  base::span<const PickerSearchResult> search_results = results[0].results();
+  if (search_results.empty()) {
+    return {};
+  }
+  return {search_results[0]};
+}
+
 }  // namespace
 
 PickerView::PickerView(PickerViewDelegate* delegate,
@@ -209,6 +222,13 @@ void PickerView::SelectZeroStateResult(const PickerSearchResult& result) {
   SelectSearchResult(result);
 }
 
+void PickerView::GetZeroStateRecentResults(PickerCategory category,
+                                           SearchResultsCallback callback) {
+  delegate_->GetResultsForCategory(
+      category,
+      base::BindRepeating(&GetMostRecentResult).Then(std::move(callback)));
+}
+
 void PickerView::GetSuggestedZeroStateEditorResults(
     SuggestedEditorResultsCallback callback) {
   delegate_->GetSuggestedEditorResults(std::move(callback));
@@ -397,7 +417,7 @@ void PickerView::AddContentsViewWithSeparator(PickerLayoutType layout_type) {
   zero_state_view_ =
       contents_view_->AddPage(std::make_unique<PickerZeroStateView>(
           this, delegate_->GetAvailableCategories(),
-          delegate_->ShouldShowRecentResults(), kMaxSize.width(),
+          delegate_->GetRecentResultsCategories(), kMaxSize.width(),
           delegate_->GetAssetFetcher()));
 
   category_view_ = contents_view_->AddPage(std::make_unique<PickerCategoryView>(
diff --git a/ash/picker/views/picker_view.h b/ash/picker/views/picker_view.h
index bbc6ddf4fae7a..0e7f5f606b381 100644
--- a/ash/picker/views/picker_view.h
+++ b/ash/picker/views/picker_view.h
@@ -73,6 +73,8 @@ class ASH_EXPORT PickerView : public views::WidgetDelegateView,
   // PickerZeroStateViewDelegate:
   void SelectZeroStateCategory(PickerCategory category) override;
   void SelectZeroStateResult(const PickerSearchResult& result) override;
+  void GetZeroStateRecentResults(PickerCategory category,
+                                 SearchResultsCallback callback) override;
   void GetSuggestedZeroStateEditorResults(
       SuggestedEditorResultsCallback callback) override;
   void NotifyPseudoFocusChanged(views::View* view) override;
diff --git a/ash/picker/views/picker_view_delegate.h b/ash/picker/views/picker_view_delegate.h
index c269d38caef4e..429b470b7065a 100644
--- a/ash/picker/views/picker_view_delegate.h
+++ b/ash/picker/views/picker_view_delegate.h
@@ -32,8 +32,9 @@ class ASH_EXPORT PickerViewDelegate {
 
   virtual std::vector<PickerCategory> GetAvailableCategories() = 0;
 
-  // Returns whether we should show suggested results in zero state view.
-  virtual bool ShouldShowRecentResults() = 0;
+  // Returns categories for which we should show recent results in zero state
+  // view.
+  virtual std::vector<PickerCategory> GetRecentResultsCategories() = 0;
 
   // Gets initially suggested results for category. Results will be returned via
   // `callback`, which may be called multiples times to update the results.
diff --git a/ash/picker/views/picker_view_unittest.cc b/ash/picker/views/picker_view_unittest.cc
index 5847477808415..567402cb96417 100644
--- a/ash/picker/views/picker_view_unittest.cc
+++ b/ash/picker/views/picker_view_unittest.cc
@@ -115,7 +115,9 @@ class FakePickerViewDelegate : public PickerViewDelegate {
     requested_case_transformation_category_ = category;
   }
 
-  bool ShouldShowRecentResults() override { return true; }
+  std::vector<PickerCategory> GetRecentResultsCategories() override {
+    return {PickerCategory::kDriveFiles};
+  }
 
   void GetResultsForCategory(PickerCategory category,
                              SearchResultsCallback callback) override {
diff --git a/ash/picker/views/picker_widget_unittest.cc b/ash/picker/views/picker_widget_unittest.cc
index 3740cfd735939..53b245558350a 100644
--- a/ash/picker/views/picker_widget_unittest.cc
+++ b/ash/picker/views/picker_widget_unittest.cc
@@ -32,7 +32,9 @@ class FakePickerViewDelegate : public PickerViewDelegate {
  public:
   // PickerViewDelegate:
   std::vector<PickerCategory> GetAvailableCategories() override { return {}; }
-  bool ShouldShowRecentResults() override { return false; }
+  std::vector<PickerCategory> GetRecentResultsCategories() override {
+    return {};
+  }
   void GetResultsForCategory(PickerCategory category,
                              SearchResultsCallback callback) override {}
   void TransformSelectedText(PickerCategory category) override {}
diff --git a/ash/picker/views/picker_zero_state_view.cc b/ash/picker/views/picker_zero_state_view.cc
index 1ddc1b56d351f..a41682e691f06 100644
--- a/ash/picker/views/picker_zero_state_view.cc
+++ b/ash/picker/views/picker_zero_state_view.cc
@@ -48,54 +48,11 @@
 #include "ui/views/view_utils.h"
 
 namespace ash {
-namespace {
-constexpr base::TimeDelta kClipboardRecency = base::Seconds(60);
-
-std::unique_ptr<PickerListItemView> CreateListItemViewForClipboardResult(
-    const PickerSearchResult::ClipboardData& data,
-    PickerListItemView::SelectItemCallback callback) {
-  auto item_view = std::make_unique<PickerListItemView>(std::move(callback));
-  item_view->SetLeadingIcon(ui::ImageModel::FromVectorIcon(
-      kClipboardIcon, cros_tokens::kCrosSysOnSurface));
-  item_view->SetSecondaryText(
-      l10n_util::GetStringUTF16(IDS_PICKER_FROM_CLIPBOARD_TEXT));
-  switch (data.display_format) {
-    case PickerSearchResult::ClipboardData::DisplayFormat::kFile:
-    case PickerSearchResult::ClipboardData::DisplayFormat::kText:
-      item_view->SetPrimaryText(data.display_text);
-      break;
-    case PickerSearchResult::ClipboardData::DisplayFormat::kImage:
-      if (!data.display_image.has_value()) {
-        return nullptr;
-      }
-      item_view->SetPrimaryImage(
-          std::make_unique<views::ImageView>(*data.display_image));
-      break;
-    case PickerSearchResult::ClipboardData::DisplayFormat::kHtml:
-      item_view->SetPrimaryText(
-          l10n_util::GetStringUTF16(IDS_PICKER_HTML_CONTENT));
-      break;
-  }
-  return item_view;
-}
-
-std::unique_ptr<PickerListItemView> CreateListItemViewForSearchResult(
-    const PickerSearchResult& result,
-    PickerListItemView::SelectItemCallback callback) {
-  // Only supports Clipboard results right now.
-  if (auto* data =
-          std::get_if<PickerSearchResult::ClipboardData>(&result.data())) {
-    return CreateListItemViewForClipboardResult(*data, std::move(callback));
-  }
-  return nullptr;
-}
-
-}  // namespace
 
 PickerZeroStateView::PickerZeroStateView(
     PickerZeroStateViewDelegate* delegate,
     base::span<const PickerCategory> available_categories,
-    bool show_recent_results,
+    base::span<const PickerCategory> recent_results_categories,
     int picker_view_width,
     PickerAssetFetcher* asset_fetcher)
     : delegate_(delegate) {
@@ -105,12 +62,11 @@ PickerZeroStateView::PickerZeroStateView(
   section_list_view_ = AddChildView(std::make_unique<PickerSectionListView>(
       picker_view_width, asset_fetcher));
 
-  if (show_recent_results) {
-    clipboard_provider_ = std::make_unique<PickerClipboardProvider>();
-    clipboard_provider_->FetchResults(
+  for (PickerCategory category : recent_results_categories) {
+    delegate_->GetZeroStateRecentResults(
+        category,
         base::BindRepeating(&PickerZeroStateView::OnFetchRecentResults,
-                            weak_ptr_factory_.GetWeakPtr()),
-        u"", kClipboardRecency);
+                            weak_ptr_factory_.GetWeakPtr()));
   }
 
   if (base::Contains(available_categories, PickerCategory::kEditorRewrite)) {
@@ -324,13 +280,9 @@ void PickerZeroStateView::OnFetchRecentResults(
         GetSectionTitleForPickerSectionType(PickerSectionType::kRecentlyUsed));
   }
   for (const auto& result : results) {
-    if (std::unique_ptr<PickerListItemView> item_view =
-            CreateListItemViewForSearchResult(
-                result,
-                base::BindRepeating(&PickerZeroStateView::OnResultSelected,
-                                    weak_ptr_factory_.GetWeakPtr(), result))) {
-      recent_section_view_->AddListItem(std::move(item_view));
-    }
+    recent_section_view_->AddResult(
+        result, base::BindRepeating(&PickerZeroStateView::OnResultSelected,
+                                    weak_ptr_factory_.GetWeakPtr(), result));
   }
   SetPseudoFocusedView(section_list_view_->GetTopItem());
 }
diff --git a/ash/picker/views/picker_zero_state_view.h b/ash/picker/views/picker_zero_state_view.h
index 2fa876a61044f..a4e0db0450131 100644
--- a/ash/picker/views/picker_zero_state_view.h
+++ b/ash/picker/views/picker_zero_state_view.h
@@ -39,7 +39,7 @@ class ASH_EXPORT PickerZeroStateView : public PickerPageView {
   explicit PickerZeroStateView(
       PickerZeroStateViewDelegate* delegate,
       base::span<const PickerCategory> available_categories,
-      bool show_suggested_results,
+      base::span<const PickerCategory> recent_results_categories,
       int picker_view_width,
       PickerAssetFetcher* asset_fetcher);
   PickerZeroStateView(const PickerZeroStateView&) = delete;
diff --git a/ash/picker/views/picker_zero_state_view_delegate.h b/ash/picker/views/picker_zero_state_view_delegate.h
index 134e76606ac95..00fee1b334318 100644
--- a/ash/picker/views/picker_zero_state_view_delegate.h
+++ b/ash/picker/views/picker_zero_state_view_delegate.h
@@ -22,10 +22,16 @@ class ASH_EXPORT PickerZeroStateViewDelegate {
   using SuggestedEditorResultsCallback =
       base::OnceCallback<void(std::vector<PickerSearchResult>)>;
 
+  using SearchResultsCallback =
+      base::RepeatingCallback<void(std::vector<PickerSearchResult>)>;
+
   virtual void SelectZeroStateCategory(PickerCategory category) = 0;
 
   virtual void SelectZeroStateResult(const PickerSearchResult& result) = 0;
 
+  virtual void GetZeroStateRecentResults(PickerCategory category,
+                                         SearchResultsCallback callback) = 0;
+
   virtual void GetSuggestedZeroStateEditorResults(
       SuggestedEditorResultsCallback callback) = 0;
 
diff --git a/ash/picker/views/picker_zero_state_view_unittest.cc b/ash/picker/views/picker_zero_state_view_unittest.cc
index 28f552ec271d1..58fbcb90c5372 100644
--- a/ash/picker/views/picker_zero_state_view_unittest.cc
+++ b/ash/picker/views/picker_zero_state_view_unittest.cc
@@ -34,6 +34,7 @@
 namespace ash {
 namespace {
 
+using ::testing::_;
 using ::testing::AllOf;
 using ::testing::Contains;
 using ::testing::ElementsAre;
@@ -79,6 +80,10 @@ class MockZeroStateViewDelegate : public PickerZeroStateViewDelegate {
               GetSuggestedZeroStateEditorResults,
               (SuggestedEditorResultsCallback),
               (override));
+  MOCK_METHOD(void,
+              GetZeroStateRecentResults,
+              (PickerCategory, SearchResultsCallback),
+              (override));
   MOCK_METHOD(void, NotifyPseudoFocusChanged, (views::View*), (override));
 };
 
@@ -92,7 +97,7 @@ class PickerZeroStateViewTest : public views::ViewsTestBase {
 
 TEST_F(PickerZeroStateViewTest, CreatesCategorySections) {
   MockZeroStateViewDelegate mock_delegate;
-  PickerZeroStateView view(&mock_delegate, kAllCategories, true, kPickerWidth,
+  PickerZeroStateView view(&mock_delegate, kAllCategories, {}, kPickerWidth,
                            &asset_fetcher_);
 
   EXPECT_THAT(view.section_views_for_testing(),
@@ -109,7 +114,7 @@ TEST_F(PickerZeroStateViewTest, LeftClickSelectsCategory) {
   MockZeroStateViewDelegate mock_delegate;
   auto* view = widget->SetContentsView(std::make_unique<PickerZeroStateView>(
       &mock_delegate, std::vector<PickerCategory>{PickerCategory::kExpressions},
-      false, kPickerWidth, &asset_fetcher_));
+      std::vector<PickerCategory>{}, kPickerWidth, &asset_fetcher_));
   widget->Show();
   ASSERT_THAT(view->section_views_for_testing(),
               Contains(Key(PickerCategoryType::kGeneral)));
@@ -129,43 +134,33 @@ TEST_F(PickerZeroStateViewTest, LeftClickSelectsCategory) {
   LeftClickOn(*category_view);
 }
 
-TEST_F(PickerZeroStateViewTest, ShowsClipboardItems) {
-  base::UnguessableToken item_id;
-  testing::StrictMock<MockClipboardHistoryController> mock_clipboard;
-  EXPECT_CALL(mock_clipboard, GetHistoryValues)
-      .WillOnce(
-          [&item_id](
-              ClipboardHistoryController::GetHistoryValuesCallback callback) {
-            ClipboardHistoryItemBuilder builder;
-            ClipboardHistoryItem item =
-                builder.SetFormat(ui::ClipboardInternalFormat::kText)
-                    .SetText("test")
-                    .Build();
-            item_id = item.id();
-            std::move(callback).Run({std::move(item)});
-          });
+TEST_F(PickerZeroStateViewTest, ShowsRecentItems) {
+  MockZeroStateViewDelegate mock_delegate;
+  EXPECT_CALL(mock_delegate,
+              GetZeroStateRecentResults(PickerCategory::kDriveFiles, _))
+      .WillOnce([](PickerCategory category,
+                   MockZeroStateViewDelegate::SearchResultsCallback callback) {
+        std::move(callback).Run({PickerSearchResult::DriveFile(
+            /*title=*/u"test drive file",
+            /*url=*/GURL(),
+            /*icon=*/{})});
+      });
 
   std::unique_ptr<views::Widget> widget = CreateTestWidget();
   widget->SetFullscreen(true);
   base::test::TestFuture<const PickerSearchResult&> future;
-  MockZeroStateViewDelegate mock_delegate;
   auto* view = widget->SetContentsView(std::make_unique<PickerZeroStateView>(
-      &mock_delegate, kAllCategories, true, kPickerWidth, &asset_fetcher_));
+      &mock_delegate, kAllCategories,
+      std::vector<PickerCategory>{PickerCategory::kDriveFiles}, kPickerWidth,
+      &asset_fetcher_));
   widget->Show();
 
-  EXPECT_CALL(
-      mock_delegate,
-      SelectZeroStateResult(Property(
-          "data", &ash::PickerSearchResult::data,
-          VariantWith<ash::PickerSearchResult::ClipboardData>(AllOf(
-              Field("item_id", &ash::PickerSearchResult::ClipboardData::item_id,
-                    item_id),
-              Field("display_format",
-                    &ash::PickerSearchResult::ClipboardData::display_format,
-                    PickerSearchResult::ClipboardData::DisplayFormat::kText),
-              Field("display_text",
-                    &ash::PickerSearchResult::ClipboardData::display_text,
-                    u"test"))))))
+  EXPECT_CALL(mock_delegate,
+              SelectZeroStateResult(Property(
+                  "data", &ash::PickerSearchResult::data,
+                  VariantWith<ash::PickerSearchResult::DriveFileData>(Field(
+                      "title", &ash::PickerSearchResult::DriveFileData::title,
+                      u"test drive file")))))
       .Times(1);
 
   ASSERT_THAT(view->RecentSectionForTesting(), Not(IsNull()));
@@ -175,35 +170,6 @@ TEST_F(PickerZeroStateViewTest, ShowsClipboardItems) {
   LeftClickOn(*item_view);
 }
 
-TEST_F(PickerZeroStateViewTest, HidesRecentSectionWhenNoItemsToDisplay) {
-  testing::StrictMock<MockClipboardHistoryController> mock_clipboard;
-  EXPECT_CALL(mock_clipboard, GetHistoryValues)
-      .WillOnce(
-          [](ClipboardHistoryController::GetHistoryValuesCallback callback) {
-            std::move(callback).Run({});
-          });
-
-  std::unique_ptr<views::Widget> widget = CreateTestWidget();
-  widget->SetFullscreen(true);
-  MockZeroStateViewDelegate mock_delegate;
-  auto* view = widget->SetContentsView(std::make_unique<PickerZeroStateView>(
-      &mock_delegate, kAllCategories, true, kPickerWidth, &asset_fetcher_));
-  widget->Show();
-
-  EXPECT_THAT(view->RecentSectionForTesting(), IsNull());
-}
-
-TEST_F(PickerZeroStateViewTest, DoesntShowClipboardItems) {
-  std::unique_ptr<views::Widget> widget = CreateTestWidget();
-  widget->SetFullscreen(true);
-  MockZeroStateViewDelegate mock_delegate;
-  auto* view = widget->SetContentsView(std::make_unique<PickerZeroStateView>(
-      &mock_delegate, kAllCategories, false, kPickerWidth, &asset_fetcher_));
-  widget->Show();
-
-  EXPECT_THAT(view->RecentSectionForTesting(), IsNull());
-}
-
 TEST_F(PickerZeroStateViewTest,
        DoesntShowEditorRewriteCategoryForEmptySuggestions) {
   MockZeroStateViewDelegate mock_delegate;
@@ -211,7 +177,7 @@ TEST_F(PickerZeroStateViewTest,
       .WillOnce([](MockZeroStateViewDelegate::SuggestedEditorResultsCallback
                        callback) { std::move(callback).Run({}); });
   PickerZeroStateView view(&mock_delegate, {{PickerCategory::kEditorRewrite}},
-                           false, kPickerWidth, &asset_fetcher_);
+                           {}, kPickerWidth, &asset_fetcher_);
 
   EXPECT_THAT(
       view.section_views_for_testing(),
@@ -239,7 +205,7 @@ TEST_F(PickerZeroStateViewTest, ShowsEditorSuggestionsAsItems) {
         });
       });
   PickerZeroStateView view(&mock_delegate, {{PickerCategory::kEditorRewrite}},
-                           false, kPickerWidth, &asset_fetcher_);
+                           {}, kPickerWidth, &asset_fetcher_);
 
   EXPECT_THAT(
       view.section_views_for_testing(),