diff --git a/packages/shared-components/__vis__/linux/__baselines__/menus/FileShare/FileList.stories.tsx/default-auto.png b/packages/shared-components/__vis__/linux/__baselines__/menus/FileShare/FileList.stories.tsx/default-auto.png new file mode 100644 index 0000000000..541c6ad3c6 Binary files /dev/null and b/packages/shared-components/__vis__/linux/__baselines__/menus/FileShare/FileList.stories.tsx/default-auto.png differ diff --git a/packages/shared-components/__vis__/linux/__baselines__/menus/FileShare/FileList.stories.tsx/loading-auto.png b/packages/shared-components/__vis__/linux/__baselines__/menus/FileShare/FileList.stories.tsx/loading-auto.png new file mode 100644 index 0000000000..94e1c4eff0 Binary files /dev/null and b/packages/shared-components/__vis__/linux/__baselines__/menus/FileShare/FileList.stories.tsx/loading-auto.png differ diff --git a/packages/shared-components/__vis__/linux/__baselines__/menus/FileShare/FileList.stories.tsx/no-files-auto.png b/packages/shared-components/__vis__/linux/__baselines__/menus/FileShare/FileList.stories.tsx/no-files-auto.png new file mode 100644 index 0000000000..e0313fe63b Binary files /dev/null and b/packages/shared-components/__vis__/linux/__baselines__/menus/FileShare/FileList.stories.tsx/no-files-auto.png differ diff --git a/packages/shared-components/__vis__/linux/__baselines__/menus/FileShare/FileList.stories.tsx/readonly-auto.png b/packages/shared-components/__vis__/linux/__baselines__/menus/FileShare/FileList.stories.tsx/readonly-auto.png new file mode 100644 index 0000000000..86a8603621 Binary files /dev/null and b/packages/shared-components/__vis__/linux/__baselines__/menus/FileShare/FileList.stories.tsx/readonly-auto.png differ diff --git a/packages/shared-components/__vis__/linux/__baselines__/menus/FileShare/GridFileList.stories.tsx/default-auto.png b/packages/shared-components/__vis__/linux/__baselines__/menus/FileShare/GridFileList.stories.tsx/default-auto.png new file mode 100644 index 0000000000..c2fcc2e288 Binary files /dev/null and b/packages/shared-components/__vis__/linux/__baselines__/menus/FileShare/GridFileList.stories.tsx/default-auto.png differ diff --git a/packages/shared-components/__vis__/linux/__baselines__/menus/FileShare/GridFileList.stories.tsx/disabled-auto.png b/packages/shared-components/__vis__/linux/__baselines__/menus/FileShare/GridFileList.stories.tsx/disabled-auto.png new file mode 100644 index 0000000000..7e5593bef6 Binary files /dev/null and b/packages/shared-components/__vis__/linux/__baselines__/menus/FileShare/GridFileList.stories.tsx/disabled-auto.png differ diff --git a/packages/shared-components/__vis__/linux/__baselines__/menus/FileShare/GridFileList.stories.tsx/with-files-selected-auto.png b/packages/shared-components/__vis__/linux/__baselines__/menus/FileShare/GridFileList.stories.tsx/with-files-selected-auto.png new file mode 100644 index 0000000000..8f2b973877 Binary files /dev/null and b/packages/shared-components/__vis__/linux/__baselines__/menus/FileShare/GridFileList.stories.tsx/with-files-selected-auto.png differ diff --git a/packages/shared-components/__vis__/linux/__baselines__/menus/FileShare/VerticalFileList.stories.tsx/default-auto.png b/packages/shared-components/__vis__/linux/__baselines__/menus/FileShare/VerticalFileList.stories.tsx/default-auto.png new file mode 100644 index 0000000000..ca86eef5f5 Binary files /dev/null and b/packages/shared-components/__vis__/linux/__baselines__/menus/FileShare/VerticalFileList.stories.tsx/default-auto.png differ diff --git a/packages/shared-components/__vis__/linux/__baselines__/menus/FileShare/VerticalFileList.stories.tsx/disabled-auto.png b/packages/shared-components/__vis__/linux/__baselines__/menus/FileShare/VerticalFileList.stories.tsx/disabled-auto.png new file mode 100644 index 0000000000..c1e3a92f6f Binary files /dev/null and b/packages/shared-components/__vis__/linux/__baselines__/menus/FileShare/VerticalFileList.stories.tsx/disabled-auto.png differ diff --git a/packages/shared-components/__vis__/linux/__baselines__/menus/FileShare/VerticalFileList.stories.tsx/with-files-selected-auto.png b/packages/shared-components/__vis__/linux/__baselines__/menus/FileShare/VerticalFileList.stories.tsx/with-files-selected-auto.png new file mode 100644 index 0000000000..bdbdd09204 Binary files /dev/null and b/packages/shared-components/__vis__/linux/__baselines__/menus/FileShare/VerticalFileList.stories.tsx/with-files-selected-auto.png differ diff --git a/packages/shared-components/src/menus/FileShare/FileList.stories.tsx b/packages/shared-components/src/menus/FileShare/FileList.stories.tsx index 4e8f0b895f..ce4ab1a652 100644 --- a/packages/shared-components/src/menus/FileShare/FileList.stories.tsx +++ b/packages/shared-components/src/menus/FileShare/FileList.stories.tsx @@ -75,6 +75,18 @@ const meta = { type: "figma", url: "https://www.figma.com/design/1UCf1hF507QaRus3CUBKGn/Nectcloud-File-Picker?node-id=2138-14865&t=njpHkpdk8tVhp7cr-0", }, + a11y: { + config: { + rules: [ + { + // TODO: We need a new folder icon, the current one is a emoji and we + // can't determine the contrast. + id: "color-contrast", + enabled: false, + }, + ], + }, + }, }, } satisfies Meta; diff --git a/packages/shared-components/src/menus/FileShare/FileList.test.tsx b/packages/shared-components/src/menus/FileShare/FileList.test.tsx new file mode 100644 index 0000000000..e152949128 --- /dev/null +++ b/packages/shared-components/src/menus/FileShare/FileList.test.tsx @@ -0,0 +1,70 @@ +/* + * Copyright 2026 Element Creations Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +import React from "react"; +import { render } from "@test-utils"; +import { composeStories } from "@storybook/react-vite"; +import { describe, it, expect } from "vitest"; +import { fn } from "storybook/test"; +import userEvent from "@testing-library/user-event"; + +import * as stories from "./GridFileList.stories"; +import { BaseViewModel } from "../../core/viewmodel"; +import type { FileShareViewModel, FileShareViewSnapshot } from "./Viewmodel"; +import { FileListView } from "./FileList"; + +const { Default } = composeStories(stories); + +class MockViewModel extends BaseViewModel implements FileShareViewModel { + public constructor(snapshot: FileShareViewSnapshot) { + super(undefined, snapshot); + } + public loadFiles = fn(); + public setCurrentDirectory = fn(); + public goBackDirectory = fn(); + public onFileSelected = fn(); + public getThumbnailForFile = fn().mockResolvedValue(null); + public setFileViewSetting = fn(); +} + +function renderView(initialSnapshot?: Partial): [ReturnType, MockViewModel] { + const snapshot: FileShareViewSnapshot = { + currentDirectory: [], + directories: [], + files: [ + { + id: "a_file", + name: "myfile.txt", + }, + ], + selectedFiles: [], + loading: false, + sending: false, + viewSetting: "list", + ...initialSnapshot, + }; + const vm = new MockViewModel(snapshot); + const result = render(); + return [result, vm]; +} + +describe("", () => { + it("renders Default story", () => { + const { container } = render(); + expect(container).toMatchSnapshot(); + }); + it("can select a file in details mode", async () => { + const [{ getByLabelText }, vm] = renderView(); + await userEvent.click(getByLabelText("myfile.txt")); + expect(vm.onFileSelected).toHaveBeenCalledWith("a_file"); + }); + it("can select a file in grid mode", async () => { + const [{ getByLabelText }, vm] = renderView({ viewSetting: "grid" }); + await userEvent.click(getByLabelText("myfile.txt")); + expect(vm.onFileSelected).toHaveBeenCalledWith("a_file"); + }); +}); diff --git a/packages/shared-components/src/menus/FileShare/GridFileList.module.css b/packages/shared-components/src/menus/FileShare/GridFileList.module.css index 976a3667b9..e60ef99a8c 100644 --- a/packages/shared-components/src/menus/FileShare/GridFileList.module.css +++ b/packages/shared-components/src/menus/FileShare/GridFileList.module.css @@ -4,8 +4,17 @@ display: grid; gap: 0 var(--cpd-space-4x); padding: var(--cpd-space-4x); - grid-template-columns: repeat(4, minmax(0, 1fr)); + grid-template-columns: repeat(auto-fit, minmax(128px, 1fr)); border-radius: var(--cpd-space-2x); + + li { + list-style: none; + gap: var(--cpd-space-3x); + > button { + width: fit-content; + } + } + button.fileTile:hover { background: var(--cpd-color-bg-action-tertiary-hovered); } @@ -17,7 +26,6 @@ label { display: block; } - gap: var(--cpd-space-3x); border: none; label { @@ -29,6 +37,8 @@ } .previewThumb { + width: 128px; + height: 128px; width: 100%; aspect-ratio: 1; background-size: cover; @@ -42,15 +52,16 @@ } .bigIcon { - width: fit-content; + max-width: 128px; + max-height: 128px; + padding: 4em; + aspect-ratio: 1; margin: 0 auto; - width: 48px; - height: 48px; color: var(--cpd-color-icon-secondary); > span { + line-height: 0.6; font-size: 36px; - margin-left: auto; - margin-right: auto; + margin: auto; } } } diff --git a/packages/shared-components/src/menus/FileShare/GridFileList.stories.tsx b/packages/shared-components/src/menus/FileShare/GridFileList.stories.tsx index f18a2a6096..e888a9176d 100644 --- a/packages/shared-components/src/menus/FileShare/GridFileList.stories.tsx +++ b/packages/shared-components/src/menus/FileShare/GridFileList.stories.tsx @@ -62,6 +62,23 @@ const meta = { type: "figma", url: "https://www.figma.com/design/1UCf1hF507QaRus3CUBKGn/Nectcloud-File-Picker?node-id=2138-14865&t=njpHkpdk8tVhp7cr-0", }, + a11y: { + config: { + rules: [ + { + // TODO: We need a new folder icon, the current one is a emoji and we + // can't determine the contrast. + id: "color-contrast", + enabled: false, + }, + { + // So that we can hide the button which is just a bigger target for the checkbox. + id: "aria-hidden-focus", + enabled: false, + }, + ], + }, + }, }, } satisfies Meta; diff --git a/packages/shared-components/src/menus/FileShare/GridFileList.tsx b/packages/shared-components/src/menus/FileShare/GridFileList.tsx index e41e7c7efc..98c9c13303 100644 --- a/packages/shared-components/src/menus/FileShare/GridFileList.tsx +++ b/packages/shared-components/src/menus/FileShare/GridFileList.tsx @@ -38,21 +38,23 @@ function DirectoryItem({ ); return ( - +
  • + +
  • ); } @@ -83,24 +85,29 @@ function FileItem({ }, [fileId, previewEngine]); return ( - +
    + +
    +
    + + {updatedAt && {i18n.humanizeTime(updatedAt.getTime())}} +
    + + ); } diff --git a/packages/shared-components/src/menus/FileShare/VerticalFileList.stories.tsx b/packages/shared-components/src/menus/FileShare/VerticalFileList.stories.tsx index 0053caf97f..58cfcee3da 100644 --- a/packages/shared-components/src/menus/FileShare/VerticalFileList.stories.tsx +++ b/packages/shared-components/src/menus/FileShare/VerticalFileList.stories.tsx @@ -55,6 +55,18 @@ const meta = { type: "figma", url: "https://www.figma.com/design/1UCf1hF507QaRus3CUBKGn/Nectcloud-File-Picker?node-id=2138-14865&t=njpHkpdk8tVhp7cr-0", }, + a11y: { + config: { + rules: [ + { + // TODO: We need a new folder icon, the current one is a emoji and we + // can't determine the contrast. + id: "color-contrast", + enabled: false, + }, + ], + }, + }, }, } satisfies Meta; diff --git a/packages/shared-components/src/menus/FileShare/VerticalFileList.tsx b/packages/shared-components/src/menus/FileShare/VerticalFileList.tsx index 7c9c89b384..3fe56f1fe8 100644 --- a/packages/shared-components/src/menus/FileShare/VerticalFileList.tsx +++ b/packages/shared-components/src/menus/FileShare/VerticalFileList.tsx @@ -62,8 +62,10 @@ function FileItem({
    onChange()} />
    - - {fileExt[0] && .{fileExt.join(".")}} +
    {updatedAt && {i18n.humanizeTime(updatedAt.getTime())}} diff --git a/packages/shared-components/src/menus/FileShare/Viewmodel.ts b/packages/shared-components/src/menus/FileShare/Viewmodel.ts index 5347a5dcc7..1e5fd49cb1 100644 --- a/packages/shared-components/src/menus/FileShare/Viewmodel.ts +++ b/packages/shared-components/src/menus/FileShare/Viewmodel.ts @@ -5,7 +5,7 @@ */ import type { ViewModel } from "../../core/viewmodel"; -import { GridFileListPreviewEngine } from "./GridFileList"; +import type { GridFileListPreviewEngine } from "./GridFileList"; export type FileId = string; export type FileShareViewSetting = "list" | "grid"; @@ -23,7 +23,6 @@ export interface FileShareViewSnapshot { } export interface FileShareActions { - loadFiles(): Promise; setCurrentDirectory(name: string): void; goBackDirectory(index?: number): void; onFileSelected(name: string): void; diff --git a/packages/shared-components/src/menus/FileShare/__snapshots__/FileList.test.tsx.snap b/packages/shared-components/src/menus/FileShare/__snapshots__/FileList.test.tsx.snap new file mode 100644 index 0000000000..dcb6f9b13f --- /dev/null +++ b/packages/shared-components/src/menus/FileShare/__snapshots__/FileList.test.tsx.snap @@ -0,0 +1,262 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[` > renders Default story 1`] = ` +
    +
      + + + + + + +
    +
    +`;