refactor(ui-primitives): extract shared head/tail cap and copy-feedback helpers
The tail-header cap fix pushed SearchBlock's head/tail slicing arithmetic and its copy-feedback hook over the duplication gate's threshold against the byte-identical logic in TerminalBlock. Extract both into head-tail-cap.ts (headTailCap) and use-copy-feedback.ts (useCopyFeedback) and consume them from both blocks, deleting the clone rather than nudging it under the limit.
This commit is contained in:
33
packages/client/ui-primitives/src/head-tail-cap.ts
Normal file
33
packages/client/ui-primitives/src/head-tail-cap.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
// Head/tail height-cap arithmetic shared by the block primitives (TerminalBlock,
|
||||
// SearchBlock) and matching the TUI transcript's collapsed tool card, so a long
|
||||
// result's head and tail slices agree across every surface. The split is
|
||||
// `ceil(maxLines / 2)` head rows and the remainder as tail rows; a result within
|
||||
// the cap shows every row and hides none.
|
||||
|
||||
/** The head/tail split metrics for a capped list. */
|
||||
export interface HeadTailCap {
|
||||
/** Rows beyond the cap (list length − maxLines); ≤ 0 means nothing is hidden. */
|
||||
hidden: number
|
||||
/** Whether the list is over the cap and not expanded, so it shows a head/tail slice. */
|
||||
capped: boolean
|
||||
/** Head-slice row count: `ceil(maxLines / 2)`. */
|
||||
headLines: number
|
||||
/** Tail-slice row count: the remainder after the head. */
|
||||
tailLines: number
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the head/tail cap metrics for a list of `total` rows against `maxLines`,
|
||||
* given whether the surface is expanded. Pure arithmetic; the caller slices its
|
||||
* own rows with `headLines`/`tailLines` so a block can layer its own concerns
|
||||
* (SearchBlock restores a tail file header) on top.
|
||||
* @param total - the list's row count.
|
||||
* @param maxLines - the collapsed-height cap in rows.
|
||||
* @param expanded - whether the surface is expanded (uncaps the list).
|
||||
* @returns the split metrics.
|
||||
*/
|
||||
export function headTailCap(total: number, maxLines: number, expanded: boolean): HeadTailCap {
|
||||
const hidden = total - maxLines
|
||||
const headLines = Math.ceil(maxLines / 2)
|
||||
return { hidden, capped: hidden > 0 && !expanded, headLines, tailLines: maxLines - headLines }
|
||||
}
|
||||
Reference in New Issue
Block a user