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

feat(@clayui/core): adds asynchronous loading for Table items with nested row #5713

Merged
merged 5 commits into from
Nov 20, 2023

Conversation

matuzalemsteles
Copy link
Member

Closes LPS-200428

This PR implements support for asynchronous loading of the node, the implementation is similar to what we have in TreeView but without support for paginated data, we can add it later when we have real use cases and we can explore the visual state of paginated data for table.

<Table
  onLoadMore={async (item) => {
    return await fetch(`example.com/tree/item?parent_id=${item.id}`);
  }}
>
  <Head items={columns}>
    {(column) => <Cell key={column.id}>{column.name}</Cell>}
  </Head>

  <Body
    defaultItems={[
      {id: 1, name: 'Games', type: 'File folder'},
      {id: 2, name: 'Program Files', type: 'File folder'},
    ]}
  >
    {(row) => (
      <Row>
        <Cell>{row.name}</Cell>
        <Cell>{row.type}</Cell>
      </Row>
    )}
  </Body>
</Table>

Copy link
Member

@ethib137 ethib137 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is looking good @matuzalemsteles

Is the deploy preview currently not working? https://deploy-preview-5713--next-storybook-clayui.netlify.app/

ref: React.Ref<HTMLTableSectionElement>
) {
const {expandedKeys, nestedKey} = useTable();

const [treeItems, setItems] = useControlledState({
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like these should be consistent: [treeItems, setTreeItems]

}}
>
{expandable && (
{(expandable || onLoadMore) && !isLoading && (
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to indicate that if this was not expandable but onLoadMore was passed as a prop that we would render the button used for expanding the row. What is the use case for this? I would think we would still only want to render the expand button if it was expandable.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah that's a big dilemma in this implementation and it's complicated, for example to say that an item is expandable we need the key for example children to be visible, so if it is not visible we make the assumption that it is not expandable in the default behavior when you have asynchronous loading the assumption we could make is if there is children but the array is empty we would consider it lazy loading but that is an assumption that we cannot guarantee is true for all use cases because the data structure in the DXP for example is different so it is difficult to make this assumption, so what we do here is always render the expandable when onLoadMore is defined but this is also not very interactive.

An idea I thought about this is we can add a property called lazy in the row to say that we should consider asynchronous loading so the developer can use any conditional he wants according to his data structure would be more flexible and we avoid assumptions.

<Table
	nestedKey="items"
	onLoadMore={async (item: any) => {
		// load more
	}}
>
	<Head items={columns}>
		{(column) => (
			<Cell className="table-cell-minw-300" key={column.id}>
				{column.name}
			</Cell>
		)}
	</Head>

	<Body defaultItems={items}>
		{(row) => (
			<Row lazy={row.items.lenght === 0}>
				...
			</Row>
		)}
	</Body>
</Table>

Let me know what you think.

@@ -242,6 +251,14 @@ export const Cell = React.forwardRef<HTMLTableCellElement, Props>(
</Layout.ContentCol>
)}

{isLoading && (
<Layout.ContentCol className="autofit-col-toggle">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is switching between a button and a div while loading going to cause the user to lose focus if they had been interacting via the keyboard?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well in this case no because when you expand via keyboard the focus is always on the Cell and not on the button, so it's safe to do that.

/**
* When a tree is very large, loading items (nodes) asynchronously is preferred to
* decrease the initial payload and memory space. The callback is called every time
* the item is a leaf node of the tree.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So it's called when the item is "currently" a leaf, because the leaf might have children that need to be loaded? Is that right?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this is the idea. We could implement paginated loading for non-leaf elements as well, as exists in TreeView, but I think it's best to wait for use cases to appear for this because it involves UI changes as well, such as where to add the button to load more, etc...

@matuzalemsteles
Copy link
Member Author

@ethib137 Did you check the example https://deploy-preview-5713--next-storybook-clayui.netlify.app/?path=/story/design-system-components-table--async-load ? I can test this behavior without any problems.

@ethib137
Copy link
Member

https://deploy-preview-5713--next-storybook-clayui.netlify.app/?path=/story/design-system-components-table--async-load

Strange... this didn't work for me this past week, but now it's working. 🤔

@matuzalemsteles matuzalemsteles merged commit 6b42508 into liferay:master Nov 20, 2023
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants