diff --git a/.trellis/spec/frontend/quality-guidelines.md b/.trellis/spec/frontend/quality-guidelines.md index 5814000..f8b9728 100644 --- a/.trellis/spec/frontend/quality-guidelines.md +++ b/.trellis/spec/frontend/quality-guidelines.md @@ -59,13 +59,26 @@ When making changes to `packages/` directory and testing with `examples/`: const DEV_MODE_TS = "2026-03-26T03:50:00.000Z"; // Update timestamp to force reload ``` +### Build Commands + +This project uses **bun** as package manager: + +| Command | Purpose | When to Use | +|---------|---------|-------------| +| `bun run dev` | Start Vite dev server | Testing example project | +| `bun run build` | Build examples project | **DO NOT USE** - examples don't need build | +| `bun run build:lib` | Build library for external repos | When done with changes, to verify build | +| `bun run lint` | Lint code | Before commit | + +**Common mistake**: Running `bun run build` which builds the examples project unnecessarily. The examples project is for development only and Vite handles hot reload automatically. + ### Quick Test Cycle ```bash # 1. Make changes to packages/ # 2. Dev server auto-reloads when accessing example pages # 3. Modify DEV_MODE_TS in packages/manage/router/index.vue if changes don't appear -# 4. Run build when done to verify +# 4. Run build:lib when done to verify bun run build:lib ``` @@ -120,6 +133,38 @@ const height = probeRowRef.value?.offsetHeight; **Verification**: All rows should have identical heights and consistent spacing. +### el-table-v2 resize with probe row (clear-then-set pattern) + +When handling window/container resize with a probe row for dynamic row height: + +**Problem**: Clearing `estimatedRowHeight` to trigger re-measure creates a visible flash (1-2 frames) where el-table-v2 uses default height. + +**Root Cause**: The gap between clearing the old value and setting the new value is visible to el-table-v2. + +**Solution**: Measure first (capturing new values), then use `queueMicrotask` to clear and set in the SAME microtask: +```typescript +// 1. Measure first while old values still set +const headerHeight = headerEl?.offsetHeight; +const rowHeight = firstRow?.offsetHeight; +const newHeader = headerHeight && headerHeight > 0 ? headerHeight : estimatedHeaderHeight.value; +const newRow = rowHeight && rowHeight > 0 ? rowHeight : estimatedRowHeight.value; + +// 2. Clear then set in same microtask (before next paint) +estimatedRowHeight.value = undefined; +estimatedHeaderHeight.value = undefined; +queueMicrotask(() => { + estimatedRowHeight.value = newRow; + estimatedHeaderHeight.value = newHeader; +}); +``` + +**Why queueMicrotask works**: It defers the set to the end of the current microtask queue, but BEFORE the next paint. So the sequence is: +- Microtask 1: `undefined` is set (triggers el-table-v2 re-measure) +- Microtask 2 (queued): New value is set +- Paint: Only one paint happens with the correct value + +**Without queueMicrotask**: The clear and set happen in separate Vue reactivity updates, causing TWO paints (one with undefined, one with new value). + --- ## Code Review Checklist diff --git a/.trellis/spec/guides/code-reuse-thinking-guide.md b/.trellis/spec/guides/code-reuse-thinking-guide.md index f9d5f99..27afc23 100644 --- a/.trellis/spec/guides/code-reuse-thinking-guide.md +++ b/.trellis/spec/guides/code-reuse-thinking-guide.md @@ -97,6 +97,22 @@ When you've made similar changes to multiple files: --- +## Gotcha: Rename Without Propagation + +**Problem**: When renaming a function, variable, or component, IDE refactoring tools update all references automatically. But if you manually rename (even with search-and-replace), you may miss some references. + +**Symptom**: Code compiles/runs but behavior is broken because some code still references the old name. + +**Example**: Renaming `debouncedMeasure` to `handleResize` but forgetting to update the call site in a ResizeObserver callback. + +**Prevention checklist**: +- [ ] **Use IDE rename** (F2 in most IDEs) - it finds ALL references +- [ ] **If manual rename**: Search for the old name with grep BEFORE renaming to find all occurrences +- [ ] **If manual rename**: Search for the new name AFTER renaming to verify all references were updated +- [ ] **Test the feature** that uses the renamed entity + +--- + ## Checklist Before Commit - [ ] Searched for existing similar code diff --git a/examples/view/base/table-v2.vue b/examples/view/base/table-v2.vue index b16fff3..c25a97f 100644 --- a/examples/view/base/table-v2.vue +++ b/examples/view/base/table-v2.vue @@ -39,7 +39,7 @@ const example = reactive({ const generateData = () => { const rows = []; const now = Math.floor(Date.now() / 1000); // Unix timestamp in seconds - const lorem = new LoremIpsum({ sentencesPerParagraph: { min: 1, max: 4 }, wordsPerSentence: { min: 5, max: 10 } }); + const lorem = new LoremIpsum({ sentencesPerParagraph: { min: 2, max: 5 }, wordsPerSentence: { min: 5, max: 20 } }); for (let i = 1; i <= 100; i++) { rows.push({ id: i, diff --git a/packages/base/data/list-table-v2.vue b/packages/base/data/list-table-v2.vue index d679677..a6909fc 100644 --- a/packages/base/data/list-table-v2.vue +++ b/packages/base/data/list-table-v2.vue @@ -6,7 +6,12 @@