23 Matching Annotations
  1. Last 7 days
    1. The bar will host more than just this button later — at minimum a search field, and eventually a sync indicator — so the action takes its place alongside the others rather than dominating the screen.

      Del

    2. empty-state{text-align:center;padding:60px 20px;color:var(--muted)} .empty-state .emoji{font-size:3rem;margin-bottom:12px} .empty-state h1{font-size:1.4rem;margin:0 0 8px 0;color:var(--fg)} .empty-state p{font-size

      Provide HTML example

    3. Centering the block, muting the text colour, and pushing the emoji to font-size 3 buys that — at a glance it reads “this is what the app looks like when it’s empty”, not “the thing is still spinning.

      Remove

    4. Disappear the second I add anything” tells me what to compute: whether both tables are empty. Because the renderer runs on every store change, I don’t need any kind of show/hide gymnastics —

      Remove

    5. The test I want to pin first is the trivial one: open the app, see the hint. (clear_state, used here and in every later test, resets IndexedDB and localStorage between cases — defined in Playwright tests.)

      Remove. The intro must simply be like: empty state at first

    6. The first time I open the app on a fresh phone there’s nothing in the store yet, and an empty page would leave me wondering whether the thing failed to load. So I want a small landing message: an emoji big enough to read across the room, the app’s name, a single line saying “no boxes yet.” It should disappear the second I add anything, no matter what — a box or just an unassigned item.

      Remove

    7. import { createMergeableStore } from 'tinybase'; import { createIndexedDbPersister } from 'tinybase/persisters/persister-indexed-db'; import { createWsSynchronizer } from 'tinybase/synchronizers/synchronizer-ws-client'; import { html, LitElement } from 'lit'; const store = createMergeableStore(); const persister = createIndexedDbPersister(store, 'organiser'); const appRootEl = document.querySelector('app-root'); function renderApp(){ appRootEl?.requestUpdate(); } // Drain the IndexedDB replay before listening: an earlier listener // would fire renderApp once per replayed write. await persister.startAutoLoad(); store.addTablesListener(renderApp); renderApp(); await persister.startAutoSave(); // startAutoSave debounces — this parallel listener bumps a counter // on each completed write so the persistence test waits on a signal, // not on a delay. let _persistSeq = 0; store.addTablesListener(async () => { await persister.save(); document.body.setAttribute('data

      Unclear what this does and what calls it

    8. Dark theme, pinned to CSS custom properties so the feature chapters can reach for var(--muted) or var(--accent) by name. --bg  #1b1d2e --card  #262a40 --fg  #e8e8f0 --muted  #8a8ea5 --accent  #f9a826 :root{ --bg:#1b1d2e; --card:#262a40; --fg:#e8e8f0; --muted:#8a8ea5; --accent:#f9a826; }

      This is not used

    9. small custom-element classes that read from properties the root passes down and dispatch events back

      That does not scale well, but should ne enough for that use case

    10. Alpine drives from its reactive store; yjs (a CRDT library — a data structure that lets multiple devices edit concurrently and merge without losing writes) drives from its document; the bridge between them is where the bugs lived

      Remove

    11. function installAppRootHandlers(root){ const on = (type, fn) => root.addEventListener(type, fn); on('open-box-form', () => openBoxForm()); on('open-item-form', e => openItemForm(e.detail || {})); on('open-catalog', () => setUI({catalogOpen: true})); on('close-catalog', () => setUI({catalogOpen: false})); on('close-form', () => closeForm()); on('submit-box', () => onBoxFormSubmit()); on('submit-item', () =>

      Like ui, mist be disseminated ithe doc