Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for additional File Browser columns #15933

Open
bollwyvl opened this issue Mar 6, 2024 · 6 comments
Open

Support for additional File Browser columns #15933

bollwyvl opened this issue Mar 6, 2024 · 6 comments

Comments

@bollwyvl
Copy link
Contributor

bollwyvl commented Mar 6, 2024

Problem

The columns shown in the File Browser can't be trivially extended, or configured very much.

Proposed Solution

  • add an extension point for registering new file browser columns
  • use the extension point for existing columns
  • make columns re-orderable (in the x-axis)
  • allow more columns to participate in the filter box
  • expose additional columns in context menu
  • make columns draggable to adjust the x-axis rank
    • store in
      • workspace?
      • settings?

Additional context

  • add FileBrowser.addColumn(options: IColumnOptions) where:
export interface IColumnOptions {
   key: string;
   headerLabel: () => string;
   headerTitle: () => string;
   headerAriaLabel: (model: Contents.IModel) => string;
   cellTitle: (model: Contents.IModel) => string;
   cellAriaLabel: (model: Contents.IModel) => string;
   headerElement: () => HTMLElement;
   cellElement: (model: Contents.IModel) => HTMLElement;
   // overloadable in settings
   rank: number;
   visible: boolean;
   // optional
   updateRequested?: ISignal; // if not handled by IModel
   compare?: (a: IModel, b: IModel) => number;  // implies sortability
   search?: (query: string, a: IModel) => number;  // implies searchability
}
  • rebuild the file
  • add filebrowser:*-column commands that take args: {key}
@krassowski
Copy link
Member

Also:

export interface IColumn<T> {
id: string;
label: string;
renderCell(data: T): ReactNode;
sort(a: T, b: T): number | undefined;
isAvailable?(): boolean;
isHidden?: boolean;
}

@bollwyvl
Copy link
Contributor Author

bollwyvl commented Mar 7, 2024

table.tsx

I think it was tried to replace the file tree with react at some point, and at ~100s of listings, which is not entirely uncommon for a folder listing, it fell down. The newer ui-components table implementation might be better (e.g. windowed rendering, which carries its own weaknesses), but this might be one of the cases where a general purpose table implementation is not going to work.

I think the prototype here would be to refactor the existing purpose-built vdom renderer to have fewer hard-coded opinions about the columns (filename, etc.) and only expose the lowest-common-denominator HTMLElement interface... some expensive things (e.g. icons) might need to be deferred entirely: if rendering one of, say, ten status icons for a given cell, a column might need to request a placeholder, and then schedule a refresh of only that node when the data is available, without triggering a table-level rerender.

Indeed, HTMLElement might be too permissive: the existing implementation uses one handler for the entire table per event type (e.g. click, contextmenu, etc.)

@tonyfast
Copy link
Contributor

tonyfast commented Mar 8, 2024

if there is work being done the file browser then there may be some improvements to the assistive technology experience that could be together.

as it is, the file browser uses an a11y anti-pattern of an unordered list where each file entry is a list item; it is represented with role=list through the unordered list element. with this pattern, assistive technology users won't be able to navigate effectively to a new column because the role is incorrect. [see screenshot[ it is nice being able to access the file browser using keyboard navigation, but the way the list is labelled is gobbledygook. the verbosity of each of the list items will create a difficult AT experience as the number of files increase. these examples reinforce there may be better semantics that will give AT and keyboard users better control over their application.

the list label for the file browser in jupyterlab

the file browser serves a single tab stop with makes it an ideal for role=grid. the grid role is used for static content and interactive controls presented in tabular form. there will be an inclination to use role=treegrid but AT support is limited. role=grid is permitted on the table element which probably has the best semantics for the an accessible file browser, and the concept of adding a column becomes more natural to consider.

using native table semantics with the role=grid exposes a few key aria properties to describe state like aria-selected, aria-sorted, aria-colindex, aria-rowindex, aria-multiselectable. hopefully, these improvements would percolate to notebook then it would truly be the best recommendation for assistive technology users.

@bollwyvl
Copy link
Contributor Author

bollwyvl commented Mar 9, 2024

The above is good insight. Some concrete gist/nbviewer examples of DOM for a matrix of cases would be a concrete way to start integrating those insights to the eventual planning and execution of this work.

Having a way to continuously assess some of those would be very good, of course: this seems like something out-of-scope of this series of PRs, but could be worked on in parallel (or as a precursor) in the galata suite, which should provide extension authors and lab maintainers the core primitives for assessing (not neccessarily failing) things like... whatever that popup is.

Some further factors that would need to be evaluated, along with accessibility, on different dimensions:

  • gradually adoptable, e.g. by runtime-configurable feature flag (not replacement-by-extension)
  • visually consistent and themable with the rest of Lab
  • performant
    • render 1e3 listings in under 20oms with the base columns
    • render 1e4 file listings with a bunch of extra columns without crashing
  • can have multiple on the page
  • embeddable in a MainAreaWidget
  • not leak memory like a sieve
  • preserve browser features
    • maintain ctrl+f to find file names
    • native scrolling of the element
    • drag-drop
      • it looks like the aria metadata for this is deprecated, with no replacement in sight

@JasonWeill
Copy link
Contributor

@bollwyvl Thank you so much for opening this issue! Would it be possible to add width to the data structure, to accommodate #3875? Columns could have a minimum width, a maximum width, and a default width, for example.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants