-
-
Notifications
You must be signed in to change notification settings - Fork 273
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
New page creation UX #2728
New page creation UX #2728
Conversation
cc @flaviendelangle might be interested in this use case, for an x-tree-view demo or for pro features.
|
packages/toolpad-app/src/toolpad/AppEditor/PagesExplorer/index.tsx
Outdated
Show resolved
Hide resolved
packages/toolpad-app/src/toolpad/AppEditor/PagesExplorer/index.tsx
Outdated
Show resolved
Hide resolved
packages/toolpad-app/src/toolpad/AppEditor/PagesExplorer/index.tsx
Outdated
Show resolved
Hide resolved
What's the reason for using a TreeView in the first place given that pages can't be nested, and collapsing the top-level doesn't seem useful? |
…/improvements/refactors
We're looking for a UX similar to the vscode file explorer. The data roughly maps on the file system and has similar functionality around create/rename. It's true that pages can't be nested (yet), we do plan to use this pattern in some places in our UI which will have nested items. So far the other places have 1 level of nesting (function files with exported functions). It could be valuable to explore whether there are other UI patterns than a tree view to represent these. We should probably remove the top-level "Pages" item. This is a leftover from a time when there were more top-level items. |
…ader component for explorer panels
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it's for the Hierarchy explorer, then I think this file can go under the toolpad/AppEditor/HierarchyExplorer
folder. Or under the shared common ancestor.
The philosphy behind the components folder is to use it for general purpose components. Basically, the missing components from MUI core
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, I'm using this component in both the hierarchy explorer and the pages explorer. It's supposed to be the header for any "explorer" panel like this.
Eventually I can make these components part of a larger one that handles any explorer panel including the header and creatable/renamable items. I guess I wanted to keep it more modular first. But maybe I should try it already.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, I can try to move the component above just enough in the project structure probably if it makes sense, might be better than in the components
folder then.
sx={pagesTreeItemSx} | ||
/> | ||
) : null} | ||
{sortBy(pages, 'name').map((page) => ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is mutating the pages
array. Best to Avoid mutating variables in the render function.
It's also running a sort i every render. Feels a bit wasteful.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I noticed it was mutable, in this particular case it doesn't have too much impact but it's better to make it immutable and memoize it, I'll do it.
* Sorts an array of objects by the value of one property. | ||
*/ | ||
export function sortBy<P extends object>(objs: P[], prop: keyof P, isAsc = true): P[] { | ||
return objs.sort((a, b) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
None of the other exports of this file mutate the source array. Feels a bit counterintuitive, and I feel like it could lead to bugs. An alternative could be to add a
export function createPropertyComparator<T>(propName: string): (a: T, b: T) => number;
and let the consumer decide whether they want to mutate their array or not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's ok to just make this method immutable, simpler and more intuitive. At first I guess I wanted it to be more like .sort
, but the way that we use it it's probably better for it just to be immutable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about a utils/dom.ts
to be a bit broader?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's fine, I wasn't really sure where to put this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good. I proposed a few tweaks regarding project organization. Other remarks:
-
🤔 For visual consistency, I feel like it would be better if these are aligned
-
Will it be confusing to remove the existing page name field? It's a bit obsolete now, but I feel like we could still offer a way to edit the name in that page options panel. Perhaps less obtrusive as the one we have now. In any case, we can keep it for a follow up PR if we leave the name existing editor in place.
The issue is that in the hierarchy explorer we need space for the little expand/collapse arrow for nestable elements. I'll see if it works to add some more padding to the pages though, might be fine.
I've actually already removed it... There's pros and cons to removing it or not, on one hand it gives the users maybe a more obvious place to change the name, but on the other hand it might be confusing how it's the same thing as renaming on the left. And it might be easier for users to associate renaming in the left panel with renaming the project files. I guess I can keep the input for now and we'll see how things go from there. |
ml: -1.5, | ||
}, | ||
}; | ||
const alphabeticallySortedPages = React.useMemo(() => sortBy(pages, 'name'), [pages]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That won't sort alphabetically. e.g. 'a' < 'B' === false
.
You might want to use .localeCompare
instead:
[...pages].sort((page1, page2) => page1.name.localeCompare(page2.name)
Or if we abstract it I'd do it as a collator
interface Collator<T> {
(a: T, b: T): number
}
function createByPropCollator<T, K extends keyof T>(propName: K, collator?: Collator<T[K]>): Collator<T>;
Typesafe, composable, easy to use with both .sort
and upcoming .toSorted
const pagesCollator = createByPropCollator<Page>('name', createAlphabeticCollator())
pages.toSorted(pagesCollator)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Uh, that's right about the alphabetical ordering... And nice, I didn't know about localeCompare
or toSorted
.
The first approach seems fine, I tried implementing the second abstraction you proposed but I'm not really sure how to? And we might not need that abstraction yet anyway...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've tried adding these as comparators
, let me know what you think and feel free to provide more feedback.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great, thanks for updating!
@apedroferreira The position of the scrollbar seems to be off on the pages section. I don't believe position: sticky/fixed should be used for headers. The UX feels off when the scrollbar extends over the header. |
Screen.Recording.2023-10-04.at.17.40.18.mov