Random Link ¯\_(ツ)_/¯ | ||
Jun 22, 2024 | » | Testing in a Monorepo
7 min; updated Jun 22, 2024
Testing Web Components While any test framework can work, it’s better to test web components in a browser environment because that’s where they’ll be used. Node-based frameworks would require too much shimming of DOM calls that’d make the tests unrepresentative. and are good options for browser-based testing. is powered by ES-build, and so is the client-side of the app; let’s go down this path and see where it leads.... |
May 28, 2024 | » | Of Stale UI and Re-renders
3 min; updated May 28, 2024
More than once, I’ve been surprised by a web component either showing data that should no longer be there, or not showing data that should be there. This page aims to reason through such cases for a better mental model of web components. Rendering Lists Both <search-bar> and <search-results> need to render a collection of N items. offers two options: looping, or using the repeat(items, keyFunction, itemTemplate) directive. const cards = html` ${cards.... |
May 5, 2024 | » | Inheritance
2 min; updated May 5, 2024
Mixins Introduced to mixins by . Didn’t know that there are passionate advocates for this, e.g., ’s “You can even look at normal subclass inheritance as a degenerate form of mixin inheritance where the superclass is known at class definition time, and there’s only one application of it.” A mix-in is an abstract subclass. This technique is especially useful in languages where a class can only have a single superclass.... |
May 5, 2024 | » | Home Page
2 min; updated May 5, 2024
When a user lands at /home, this UI is shown. A couple of components are shareable from /browse, e.g., search-bar, search-results. Sharing Code with /browse Components initially created for the /browse page are useful in /home as well. The CardsViewingPage Interface This functionality can be shared between the two pages: export class CardsViewingPage extends LitElement { @provide({ context: searchResultsContext }) @state() protected searchResults: CardSearchResult[] = []; @state() protected selectedResult: Card | null = null; @provide({ context: cardsCarouselContext }) @state() protected cardsCarousel = new CardsCarousel([]); protected cardFetcher: CardFetchEndpoint; constructor(cardFetcher: CardFetchEndpoint) { super(); this.... |
May 3, 2024 | » | Reusable Cards
4 min; updated May 3, 2024
Context How can I reuse code in these user experiences? Current card templates. TL: editable card owned by the user. TR: the overall modal experience. BL: a publicly viewable card. BR: a card owned by the user but is in the trash. The current API surface for the different types of UIs is: interface EditableCardViewer { displayNewCard(): void; displayFullCard(cardId: string): void; renderCard(card: Partial<ICard> | null): void; fetchCard(caller: () => Promise<Partial<ICard> | null>): void; fetchPreviousCard(): void; fetchNextCard(): void; updateStreakBar(streak: IStreak): void; handleInputChange(elementId: string): void; handleCardUrgencyChange(): void; handleTagsInputChange(ev: KeyboardEvent): void; displayRawCardDescription(): void; insertTabsIfNecessary(ev: KeyboardEvent): void; saveCard(renderAfterSave: Boolean = true): void; moveCardToTrash(): void; restoreCardFromTrash(cardId: string, cardUrgency: number): void; toggleOption(elementId: "reviewModeToggle" | "card_is_public_toggle"): void; makeInvisible(elementId: string): void; colorUrgencyQuartiles(quartiles: number[]): void; suggestNewTags(tagsInputElement: HTMLInputElement): void; removeTagSuggestions(): void; updateTagsButtons(newTag: string): void; removeTagFromCard(tag: string): void; } interface PublicCardViewer { displayFullCard(cardId: string): void; renderCard(card: Partial<ICard> | null): void; fetchPreviousCard(): void; fetchNextCard(): void; handleSearchInputChange(): void; flagCard(reason: "markedForReview" | "markedAsDuplicate"): void; copyCardToOwnCollection(); } interface TrashedCardViewer { renderTrashedCard(card: Partial<ICard> | null); fetchPreviousCard(): void; fetchNextCard(): void; modifyTrash(endpoint: "/delete-card" | "/restore-from-trash"): void; } The web components v0 has:... |
Apr 20, 2024 | » | Browse Page
3 min; updated Apr 20, 2024
When a user lands at /browse, this UI is shown. A couple of components seem to emerge: search-bar, tags-list, card-results, and mini-card. <search-bar> Currently, this is rendered by search_bar_dropdown.ejs, a partial that that is included in both /home and /browse. The fact that there it has JS, no server-delivered content, and has CSS makes it a good candidate for a web component. Revving up search-bar.ts. Ran into Uncaught TypeError: Class constructor s cannot be invoked without 'new' on the export class SearchBar extends LitElement line.... |