Extract project components; add ConfirmDialog - #149
Merged
Merged
Conversation
The pieces of a "your projects" page that ml-trainer and the Python Editor prototype had each written, lifted from ml-trainer with the app-specific parts turned into props: - ProjectCard: actions row (optional selection checkbox, more menu with open, rename, duplicate and delete, hidden skip-to-toolbar link for keyboard users), the app's own content in the middle, the name as the card's link and when it was last modified. Apps pass a ProjectSummary (id, name, timestamp) or a superset. - ProjectsToolbar, SearchInput, SortInput: the controls above the grid. - NameProjectDialog and ConfirmDialog. - useProjectActions: the rename, duplicate and delete flows behind the card menus and the toolbar. Renders the two dialogs, tracks which project is being acted on and returns focus to the menu button that opened a dialog. The app supplies what each action does and logs what it wants. - rankProjects, sortProjects and useProjectSelection for the list state, with the app supplying secondary search terms (file names, action names). formatTimeAgo for the card's relative time. Page layout, the grid, the home page carousel and where the toolbar sits at each width stay app-side; the "Projects page example" story shows one composition. Short-viewport tweaks that used ml-trainer's own Panda condition go through the card's bodyCss prop rather than into the shared code.
A confirm dialog is a standard overlay, not a project thing: ml-trainer uses it for settings and data samples as well, and the Python Editor has its own. It now sits beside Modal, with the Cancel string, and shows under Overlays in Storybook. ui-patterns uses it from there. The peer ranges of ui-patterns and ui-carousel move to the next @microbit/ui minor, which this needs.
- Separate onRename and onDuplicate callbacks on ProjectCard and ProjectsToolbar, and rename/duplicate on the hook, instead of one callback with a "rename" | "duplicate" discriminator that leaked the shared dialog's implementation into every caller. - The card passes its menu button to the action callbacks instead of exposing a setFinalFocusRef prop; the hook hands it to the dialog to return focus to, since the menu has closed by then. - The card's relative time is a <time> element with the ISO datetime and the full date as its title, so hover and assistive tech can get the exact date. - SearchInput is type="search" for the searchbox role, with WebKit's native clear button hidden in favour of ours.
Deploying ui with
|
| Latest commit: |
67c491c
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://994a6fab.ui-2wg.pages.dev |
| Branch Preview URL: | https://project-components.ui-2wg.pages.dev |
| }, | ||
| "peerDependencies": { | ||
| "@microbit/ui": "^0.4.0", | ||
| "@microbit/ui": "^0.5.0", |
Contributor
Author
There was a problem hiding this comment.
This is a bit weird but OK, we'll have to release ui-v0.5.0 first then ui-patterns-0.7.0.
| * A rounded search box with a leading icon and a clear button while there | ||
| * is text. Clearing returns focus to the box. | ||
| */ | ||
| export const SearchInput = ({ |
Contributor
Author
There was a problem hiding this comment.
Extracted faithfully, but I think it might be worth a discussion about this rounding. Do we really want it here?
Classroom has this rounding... but the base UI components do not and they don't when used in other locations (dialogs, edit project name in ml-trainer).
Contributor
Author
There was a problem hiding this comment.
Contributor
Author
There was a problem hiding this comment.
Decoupling this from this PR, so for now we just extract what we have in ml-trainer.
- Toolbar delete with a single selection resolves to that project, so the confirmation names it rather than saying "1 projects"; the multi-delete text gains an ICU plural. - NameProjectDialog shows the empty-name error only once edited, and selects the name on the first focus after opening rather than every focus. - Rename SearchInput/SortInput/SortDirection to Project*; the hook's requestDelete to delete; ProjectCard's onSelected to onToggleSelected. - useProjectActions takes selectedIds as an array, not a getter. - ProjectsToolbar forwards a handle whose focus() lands on its first button, so onSkipToToolbar needs no DOM query; the page example wires it. - Logical properties for the card action radii and margin, the name's text alignment and the toolbar divider. - sortProjects takes an optional locale, collating with Intl.Collator.
The "select the name on first focus" flag was a ref reset during the render-time adjustment that runs when the dialog opens, which react-hooks/refs rejects. Make it state instead, so it resets alongside the name and edited flags.
| "description": "Heading of the dialog confirming deletion of several projects" | ||
| }, | ||
| "ui-patterns.delete-projects-confirm-text": { | ||
| "defaultMessage": "Are you sure you want to delete {numProjects, plural, one {# project} other {# projects}}?", |
Contributor
Author
There was a problem hiding this comment.
I changed this one string to use ICU plurals, will have to deal with some translation fallout.
The reducer kept ids of deleted projects in its raw state. selectedIds filtered them against the live list, but lastSelectedIds (used by the sliding-out toolbar) did not, so deleting two projects then selecting a third showed "Delete 3 projects" in the bottom toolbar while the top count was correct. The toggle now works from the live selection. Pruning happens there rather than when the list changes so the toolbar keeps its count while it slides out after a delete.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.