mirror of
https://github.com/azaion/ui.git
synced 2026-06-21 10:41:10 +00:00
[AZ-447] autodev Steps 1-4 baseline: docs, tests, refactor specs
Captures the full output of autodev existing-code Phase A through Step 4 (Code Testability Revision) for the Azaion UI workspace: - Step 1 Document: _docs/02_document/ (FINAL_report, architecture, glossary, components/, modules/, diagrams/, system-flows, module-layout) plus _docs/00_problem/ + _docs/01_solution/ + _docs/legacy/ + _docs/how_to_test + README. - Step 2 Architecture Baseline: architecture_compliance_baseline.md. - Step 3 Test Spec: _docs/02_document/tests/ (environment, test-data, blackbox/performance/resilience/security/ resource-limit tests, traceability-matrix), enum_spec_snapshot, expected_results/results_report.md (98 rows), plus the run-tests.sh + run-performance-tests.sh runners. - Step 4 Code Testability Revision: 01-testability-refactoring/ run dir (list-of-changes C01-C07, deferred_to_refactor, analysis/research_findings + refactoring_roadmap) and the 7 child task specs AZ-448..AZ-454 under _docs/02_tasks/todo/ plus _dependencies_table.md. - _docs/_autodev_state.md pins the cursor at Step 4 / refactor Phase 4 entry so /autodev resumes cleanly. Epic AZ-447 (UI testability gates) tracks the 7 child tasks that will land in subsequent commits. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
# Module: `src/hooks/useResizablePanel.ts`
|
||||
|
||||
> **Source**: `src/hooks/useResizablePanel.ts` (33 lines)
|
||||
> **Topo batch**: B1 (leaf)
|
||||
|
||||
## Purpose
|
||||
|
||||
React hook that backs a draggable splitter between two horizontally-arranged panels. Owns the panel width as state and exposes a mouse handler the host attaches to the splitter element.
|
||||
|
||||
## Public interface
|
||||
|
||||
```ts
|
||||
export function useResizablePanel(
|
||||
initialWidth: number,
|
||||
min?: number, // default 100
|
||||
max?: number, // default 600
|
||||
): {
|
||||
width: number
|
||||
onMouseDown: (e: React.MouseEvent) => void
|
||||
setWidth: React.Dispatch<React.SetStateAction<number>>
|
||||
}
|
||||
```
|
||||
|
||||
`width` is the current panel width (px). `onMouseDown` should be wired to the splitter element. `setWidth` is exposed for programmatic resets — currently unused by callers but kept for parity with the persistence story (see Notes).
|
||||
|
||||
## Internal logic
|
||||
|
||||
1. `useState(initialWidth)` for `width`.
|
||||
2. Drag bookkeeping is held in three `useRef` cells (`dragging`, `startX`, `startWidth`) — kept out of state so the move/up handlers never re-render the host.
|
||||
3. `onMouseDown` (memoized via `useCallback([width])`) snapshots `clientX` and `width`, marks `dragging = true`, and calls `e.preventDefault()` to avoid triggering text selection.
|
||||
4. A `useEffect` registers global `mousemove` / `mouseup` listeners on `window`. While `dragging.current === true`, `mousemove` updates `width` to `clamp(startWidth + (e.clientX - startX), min, max)`. `mouseup` flips `dragging` back to `false`.
|
||||
5. The effect cleans up on unmount.
|
||||
|
||||
## Dependencies
|
||||
|
||||
- **Internal**: none.
|
||||
- **External**: `react` (`useState`, `useCallback`, `useRef`, `useEffect`).
|
||||
|
||||
## Consumers (intra-repo)
|
||||
|
||||
- `src/features/annotations/AnnotationsPage.tsx` — left + right panel widths.
|
||||
- `src/features/dataset/DatasetPage.tsx` — left + right panel widths.
|
||||
|
||||
Both pages persist their layout server-side via `UserSettings.{annotationsLeftPanelWidth, annotationsRightPanelWidth, datasetLeftPanelWidth, datasetRightPanelWidth}` (see `src/types/index.ts`). The persistence read/write happens in the page, not in this hook.
|
||||
|
||||
## Data models
|
||||
|
||||
None.
|
||||
|
||||
## Configuration
|
||||
|
||||
None.
|
||||
|
||||
## External integrations
|
||||
|
||||
DOM only — `window.addEventListener('mousemove' / 'mouseup')`.
|
||||
|
||||
## Security
|
||||
|
||||
None.
|
||||
|
||||
## Tests
|
||||
|
||||
None.
|
||||
|
||||
## Notes / open questions
|
||||
|
||||
- The hook is keyboard- and touch-blind: only mouse drag is supported, so accessibility for non-pointer input is missing. Track for the broader a11y pass; out of scope for `/document`.
|
||||
- `setWidth` is exposed but no current caller hydrates `initialWidth` from `UserSettings` via it — they pass the persisted width directly to `useResizablePanel(persistedWidth)` on mount. If the persisted width arrives **after** mount (asynchronous load), the panel jumps. Flag for the consumers' module docs (B8).
|
||||
- Default bounds (100 / 600) are arbitrary; consumer pages may want different ceilings (e.g., the annotations sidebar). Currently both consumers accept the defaults.
|
||||
Reference in New Issue
Block a user