I am a...
- ๐ Computer Science student at the University of Missouri
- ๐ฅ๏ธ Linux enthusiast
- ๐ง Bash wizard
- ๐ฆ rustacean
Restructure modal (& trigger) components to make them easier and more ergonomic to use. Users of the modal component should not have to wrap the trigger in a <Modal>...</Modal>
.
It might also be nice to have a generic Modal
component that can take the name of the variant that forwards the props to the real modal component (with full type info).
ComponentThatUsesModalX.svelte
:
<script lang="ts">
import Modal from 'svelte-simple-modal';
import XModalTrigger from './XModalTrigger.svelte';
</script>
<Modal>
<XModalTrigger />
</Modal>
XModalTrigger.svelte
:
<script lang="ts">
import type { Context } from 'svelte-simple-modal';
import XModal from './XModal.svelte';
const { open } = getContext<Context>('simple-modal');
function on_click(event: ClickEvent) {
open(
XModal,
{ /* XModal props... */ },
{ /* modal config... */ },
);
}
</script>
<button on:click={on_click}>Open Modal</button>
XModal.svelte
:
<p>Content</p>
ComponentThatUsesModalX.svelte
:
<script lang="ts">
import XModal from './XModal.svelte';
</script>
<XModal />
XModal.svelte
:
<script lang="ts">
import { type Context, Modal } from 'svelte-simple-modal';
import XModalContent from './XModalContent.svelte';
const { open } = getContext<Context>('simple-modal');
function on_click(event: ClickEvent) {
open(
XModalContent,
{ /* XModal props... */ },
{ /* modal config... */ },
);
}
</script>
<Modal>
<button on:click={on_click}>Open Modal</button>
</Modal>
XModalContent.svelte
:
<p>Content</p>
An empty list should be the same height as a list with 1 row.
Currently, it looks like the min height of lists doesn't account for top and bottom margin/padding.
SvelteKit has some helpful docs for deploying SvelteKit applications in a node environment.
Since the beginning of this application list order has been determined by order of creation (or by editing the app data by hand). Add a list order modal.
switch-vertical
Tabler Icon for the button.Currently, when an API endpoint fails and returns a non-success code, it does so silently. When this occurs (usage of endpoint_err()
) it should be logged to the console.
Rework drag & drop (DND) to be JS-only, not using the browser's API. This will open the door for more and better features due to the browser's DND limitations.
A promising library is Svelte DND Action which claims to be "production ready". It appears to be rich enough in features to support what I want.
All buttons have the same set of styles that remove the browser's defaults:
background-color: transparent
border: none
padding: 0px
Put these in the global CSS and deduplicate the styles.
Add playwright tests for UI components.
Will these have to be run separately from the current unit tests that use Vitest? Can they be run together?
Now that there is an edit mode that encapsulates some editing functionality, as much of the other editing functionality as makes sense should be moved to it as well.
Move the delete list functionality into edit mode.
The delete button should only be visible when in edit mode, to the right of the add repo button.
Edit mode in the repo lists store is working great but is a little rigid. If you enter edit mode and immediately refresh the page you still get the unsaved changes popup. The store should track its dirty state and that should be used for the popup.
Implement hashing for the entire store data and track it on edit mode change.
Dropping a repo on a list that already has it causes a bug. The duplicate repo ID is added to the list but this causes errors for svelte rendering due to the repos being in a keyed each.
The UI should prevent a duplicate repo from being added to a list with some visual indicator.
Enable the "disabled layer" on the list while dragging over it like done with the All Repos list.
The store should also prevent this from happening (if the UI logic doesn't sufficiently prevent it).
If the ID is already in the list, then throw an exception.
Maybe it's also worth having an extra safeguard on store load/write. On deserialization, we can manually implement Lodash's keyBy
that warns and skips duplicates. On serialization, we can unique the list by running it through a Set
.
Add an edit button next to the profile menu that enables edit mode.
This is a large feature that will be broken down into several issues. This one just sets up the edit mode and moves existing edit functionality (add repos button) into it.
In edit mode, the edit button is replaced with edit controls. This is a submit button and a cancel button. List controls are also replaced with edit list controls. For now, this is just the add repos button. All list changes (repo rearranging & adding) are postponed until the edit is submitted.
The current algorithm for determining where to insert a card that's about to be dropped into a list is simple: find the card in the list that is closest to the mouse, and the side of it that is closest to the mouse. If the closest side is the left/right of a card then the dragged card is inserted before/after it. This works well in most cases, except when dragging in the trailing gap of a list -- when there aren't enough cards to fill all columns of the last row:
In this situation, the most intuitive behavior is for the calculated drop location to be the end of the list (index=3) despite the fact that the right side of the second card (index=2) is closest to the mouse.
Creating UIs from scratch is fun but it's hard work, and I'm no designer. Reworking the UI with a component library will make it look much cleaner and more polished, adding new elements will be much faster, and everything will be much more accessible.
There are a lot of good choices, here are the ones I've picked out (ranked):
Once a component library is integrated into the app, it would be good to have a comprehensive theme. Some of the libraries have built-in support for themes:
The others will likely require a custom (or another 3rd-party) solution.
Here's a useful palette generator tool (made for tailwind but can be useful regardless).
For the POC it made sense to have one global store with all app data. Now that there is more data and there are more stores it makes the most sense to separate them.
Now that repos can only be moved in edit mode -- and it doesn't make much sense to allow navigation to a repo in edit mode -- the link UX can be simplified. The cards themselves can be links. Clicking anywhere in a card (not just on the name) will navigate to the repo in GH. Hovering on the card should underline the name to indicate available user interaction.
This will make for a smoother UX because currently, to navigate to a repo, you have to click on the little icon that appears on hover.
Now that there is an edit mode there needs to be a way to remove repos from a list (I know, it's still not a feature yet).
When in edit mode a checkbox appears on each repo (where the navigate button used to be). Repo selection is tracked individually by each list. This means that each list has a delete button that only appears when repos are selected. The button only deletes repos in that list.
Now that there is an edit mode that encapsulates some editing functionality, as much of the other editing functionality as makes sense should be moved to it as well.
Move the create new list functionality into edit mode.
The new list button should only be visible when in edit mode, to the left of the global edit mode controls in the header. There should be a vertical divider separating it from the submit and cancel buttons.
@import
syntax to @use
.loadPaths
in svelte.config.js
for easy importing.When a card is dropped outside of a list it should be removed.
It would be nice to have a visual indicator for this.
Repo cards are big, and having multiple lists quickly makes the page much taller than the viewport, meaning the header will not be in the viewport a lot of the time. Now that more functionality lives in the header, having it always visible is more desirable.
For now, simply making the header sticky to the top of the viewport is good enough. Eventually, it may be desired to have it collapse when scrolling down and re-open when the user starts to scroll up.
Currently, when a card is dropped within a list to reorder, on drop it snaps back to its original position and they all animate at the same time to their new position. This is fine, but it could be better.
Instead, the card should animate directly from the mouse to its new position.
The card is replaced with an invisible one and absolutely positioned to the mouse.
This is certainly more complex than it sounds. Will the browser drag & drop play well with cards being absolutely positioned out of the list? What if they have to be removed as a child element for this to work? Will the FLIP animation work as expected moving the card back into the list? Will this affect other animations (e.g. moving cards between lists)?
Now that cards are only draggable in edit mode, attempting to drag a card will select the text. Disable this with user-select: none
.
Although, we may want to allow selecting repo names as that might be expected behavior.
Add buttons, that will be present only in development mode, that populate hard-coded data. This will be helpful for testing.
The styling of the edit controls on each repo list is inconsistent. Make them more uniform.
Inconsistencies:
Additionally, there are now 2 buttons that appear when repos are selected. These should be separated from the rest by a divider. Maybe their (dis)appearance should be animated, too.
Due to Svelte's directory-based routing components can be kept in src/routes
. Move non-shared UI components to be with their routes to clean up the lib
directory.
When in edit mode, and the browser attempts to navigate to another page, the user should be warned that they may lose their changes.
To have the browser warn the user, preventDefault
on the beforeunload
event.
window.addEventListener('beforeunload', e => {
e.preventDefault();
});
Data kept in local storage can easily be lost. And while it was a good solution for a POC, it would be very annoying to have local storage cleared. Instead, use wasm-git to store app data in a git repo on GitHub.
A simple solution is to commit-and-push the lists on each update. But this could generate too much traffic so it might be better to let changes build up in a queue and sync/autosave on a fixed interval (e.g. 30s). With the latter, it would be best to also provide a save button for the user that dynamically updates to show the save state.
Save states for a dynamic autosave button:
There are several sets of submit/accept/yes & cancel/no buttons, all with slightly different styling:
and there may be more in the future.
Extract these 2 buttons into $lib/ui
so that they can be reused.
Like local storage (#1), this was simple and simple and easy for a POC but it is cumbersome to deal with in practice.
A better solution is to have a button on each list that opens a multi-select modal to choose repos to add to the list.
There are 2 good libraries I've found that provide a multi-select component:
Some of the buttons have consistent styling to indicate their interactivity. On hover, they change color or get brighter. However, some buttons don't: the edit controls on each list produce no style change on hover. They feel a bit "static" and unresponsive.
Make some style change on hover for the edit controls on each list so that they are more interactive.
The current create list button isn't very obvious or pretty.
Maybe the button should be a mini card with a dashed border.
Now that SvelteUI has been introduced into the codebase with #24 we can start overhauling parts of the app with SvelteUI.
Rebuild the 3 modals with SvelteUI:
Now that the core edit functionality has been implemented within the new edit mode, it's time to move on to other things.
Add an edit button next to each list title. Clicking the button switches the list header into title edit mode, where the title text element is replaced with an input that has a cancel and submit button to the right. The input should expand to fill the available space in the header.
When in edit mode, repos in a list can be selected to bulk delete them from the list. It would also be useful to move repos to another list when reorganizing.
Add another button to the list edit controls that removes the repos from the current list and adds them to another. The button opens a select menu (similar to the add repos modal) that allows the user to select one target list. Like the bulk delete button, this button should only be visible when 1 or more repos are selected.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.