# To AI Agent: Refactor Itinerary Timeline into an Exclusive File Tree Directory System (Single Expansion Mode) ## 1. Context & Architectural Analogy We are refactoring the `ItineraryTimeline` component on the mobile view (`yotrip.labz.io.vn`) using a **File Tree Directory System** analogy: - **Parent Folders ("Thư mục mẹ"):** Represented by the Stages ("Chặng 1", "Chặng 2"...). - **Child Nodes ("Thư mục con"):** Represented by the Locations/Destinations inside that stage (`Trần Cao Vân`, `Đồng Khởi`...). ### CRITICAL LOGIC CONSTRAINT (Exclusive Accordion): - When a Parent Folder (Stage) is **collapsed**, all of its Child Nodes (Locations) must immediately hide cleanly inside it. - **Single Expansion Rule:** The system must enforce an **exclusive single-expansion mode**. On the entire timeline screen, **MAXIMUM ONE** Parent Folder can be expanded at any given time. - Opening/Expanding a new Stage folder must **automatically collapse** whichever Stage folder was previously open. --- ## 2. State Management Specification (For Script/Logic Implementation) To enforce the "Maximum 1 Expanded Folder" rule, do NOT use isolated individual boolean flags for each stage. Instead, implement a centralized single-active-state variable: ```javascript // Example React State Hook Blueprint: // Track the ID or index of the single active expanded stage folder. // If null, all stages are collapsed. const [expandedStageId, setExpandedStageId] = useState(initialStageId); const handleStageToggle = (stageId) => { // If clicking the already open folder, close it. Otherwise, open the new one and shut the rest. setExpandedStageId(prevId => prevId === stageId ? null : stageId); }; ## 3. Component DOM Tree & CSS Blueprint ### A. Component Layout Structure
...
2

Chặng 2

Trần Cao Vân
Đồng Khởi
### B. Core CSS Layout Styles .file-tree-itinerary-container { display: flex !important; flex-direction: column !important; height: 100dvh !important; width: 100vw !important; overflow: hidden !important; } .directory-scroll-viewport { flex: 1 1 0% !important; overflow-y: auto !important; padding: 0 !important; margin: 0 !important; background-color: #f8fafc; } /* Base style for folder blocks stacked flush against each other */ .folder-node-wrapper { width: 100% !important; background-color: #ffffff; margin-bottom: 1px !important; /* Micro hair-line divider between folders */ display: flex; flex-direction: column; } .folder-header-row { width: 100%; padding: 12px 16px !important; display: flex; align-items: center; background-color: #ffffff; cursor: pointer; /* Sticky behavior remains active when scrolling within an open directory */ position: sticky !important; top: 0px; z-index: 30; } /* CSS Grid Transition Engine for smooth directory expansions */ .folder-child-content-box { display: grid !important; grid-template-rows: 0fr; transition: grid-template-rows 0.25s cubic-bezier(0.4, 0, 0.2, 1) !important; width: 100%; } .child-nodes-list { overflow: hidden; min-height: 0px; padding: 16px; display: flex; flex-direction: column; gap: 12px; } /* --- MUTUALLY EXCLUSIVE STATE STYLES --- */ /* Collapsed Folder: Sub-files shrink immediately to 0 height */ .folder-node-wrapper.collapsed .folder-child-content-box { grid-template-rows: 0fr !important; } /* Expanded Folder: Opens dynamically to accommodate dynamic content height */ .folder-node-wrapper.expanded .folder-child-content-box { grid-template-rows: 1fr !important; } ## 4. Acceptance Criteria for AI Agent Verification [ ] Mutually Exclusive Test: Clicking an inactive Stage header while another stage is open must trigger a simultaneous transition: the old stage collapses back into a tight header row, and the clicked stage expands its location cards. [ ] Zero-Gap Validation: All collapsed folder components must sit completely flush against the top tab block and one another, eliminating all gray margin bleeding. [ ] Under-Clip Containment: When scrolling a long open folder, the list items must slide behind their sticky active parent folder row and disappear without visual overlapping artifacts.