feat(web): fold the search truncation total into the summary line
Replace the separate '已截断 · 共 N' pill with '显示 X / 共 N 处匹配 · K 个文件' (and '显示 X / 共 N 个路径' for glob), mirroring the read card's '显示 X / Y 行', so the retained count and the pre-cap total read as one clause instead of two numbers that appear to disagree.
This commit is contained in:
@@ -37,11 +37,6 @@
|
|||||||
color: var(--dsw-alias-label-secondary);
|
color: var(--dsw-alias-label-secondary);
|
||||||
}
|
}
|
||||||
|
|
||||||
.truncated {
|
|
||||||
flex: none;
|
|
||||||
color: var(--dsw-alias-state-business-primary);
|
|
||||||
}
|
|
||||||
|
|
||||||
.copyButton {
|
.copyButton {
|
||||||
flex: none;
|
flex: none;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
|
|||||||
@@ -10,7 +10,6 @@
|
|||||||
import { useCallback, useMemo, useState, type ReactNode } from 'react'
|
import { useCallback, useMemo, useState, type ReactNode } from 'react'
|
||||||
import clsx from 'clsx'
|
import clsx from 'clsx'
|
||||||
import { writeClipboard } from './clipboard.ts'
|
import { writeClipboard } from './clipboard.ts'
|
||||||
import { Pill } from './Pill.tsx'
|
|
||||||
import css from './SearchBlock.module.css'
|
import css from './SearchBlock.module.css'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -109,17 +108,22 @@ function shownCount(props: SearchBlockProps): number {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The banner summary: the structural count of the retained result. The
|
* The banner summary. When the search was capped it reads `显示 X / 共 N …` so
|
||||||
* truncation pill beside it carries the capped-vs-complete signal, so this
|
* the retained count and the pre-cap total sit in one clause (mirroring the read
|
||||||
* stays a plain count of what the card holds.
|
* card's `显示 X / Y 行`); when it was not capped it is a plain count of what the
|
||||||
|
* card holds. The unit — `处匹配 · K 个文件` for grep, `个路径` for glob — trails
|
||||||
|
* the count either way.
|
||||||
* @param props - the card's props.
|
* @param props - the card's props.
|
||||||
* @param shown - the retained result count from {@link shownCount}.
|
* @param shown - the retained result count from {@link shownCount}.
|
||||||
|
* @param truncated - whether the search was capped.
|
||||||
|
* @param total - the pre-cap total the truncation clause reports.
|
||||||
* @returns the summary text.
|
* @returns the summary text.
|
||||||
*/
|
*/
|
||||||
function summaryText(props: SearchBlockProps, shown: number): string {
|
function summaryText(props: SearchBlockProps, shown: number, truncated: boolean, total: number): string {
|
||||||
|
const count = truncated ? `显示 ${shown} / 共 ${total}` : `${shown}`
|
||||||
return props.kind === 'paths'
|
return props.kind === 'paths'
|
||||||
? `${shown} 个路径`
|
? `${count} 个路径`
|
||||||
: `${shown} 处匹配 · ${props.files.length} 个文件`
|
: `${count} 处匹配 · ${props.files.length} 个文件`
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -227,8 +231,7 @@ export function SearchBlock(props: SearchBlockProps) {
|
|||||||
return (
|
return (
|
||||||
<div className={clsx(css.block, className)} data-search={props.kind}>
|
<div className={clsx(css.block, className)} data-search={props.kind}>
|
||||||
<div className={css.header}>
|
<div className={css.header}>
|
||||||
<span className={css.summary}>{summaryText(props, shown)}</span>
|
<span className={css.summary}>{summaryText(props, shown, truncated, total)}</span>
|
||||||
{truncated && <Pill className={css.truncated}>{`已截断 · 共 ${total}`}</Pill>}
|
|
||||||
{!empty && (
|
{!empty && (
|
||||||
<button type="button" className={css.copyButton} onClick={onCopy}>
|
<button type="button" className={css.copyButton} onClick={onCopy}>
|
||||||
{copied ? '复制成功' : '复制'}
|
{copied ? '复制成功' : '复制'}
|
||||||
|
|||||||
@@ -61,10 +61,10 @@ describe('SearchBlock matches kind', () => {
|
|||||||
expect(lines(view.container)).toEqual(['1: x', '2: y'])
|
expect(lines(view.container)).toEqual(['1: x', '2: y'])
|
||||||
})
|
})
|
||||||
|
|
||||||
it('shows the truncation pill with the pre-cap total', () => {
|
it('folds the pre-cap total into the summary when truncated', () => {
|
||||||
const view = render(<SearchBlock kind="matches" truncated total={99} files={[group('a.ts', 2)]} />)
|
const view = render(<SearchBlock kind="matches" truncated total={99} files={[group('a.ts', 2)]} />)
|
||||||
expect(view.getByText('已截断 · 共 99')).toBeTruthy()
|
expect(view.getByText('显示 2 / 共 99 处匹配 · 1 个文件')).toBeTruthy()
|
||||||
expect(view.getByText('2 处匹配 · 1 个文件')).toBeTruthy()
|
expect(view.queryByText(/已截断/u)).toBeNull()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -77,9 +77,10 @@ describe('SearchBlock paths kind', () => {
|
|||||||
expect(fileHeaders(view.container)).toEqual([])
|
expect(fileHeaders(view.container)).toEqual([])
|
||||||
})
|
})
|
||||||
|
|
||||||
it('shows the truncation pill with the pre-cap total', () => {
|
it('folds the pre-cap total into the paths summary when truncated', () => {
|
||||||
const view = render(<SearchBlock kind="paths" truncated total={50} paths={['a', 'b']} />)
|
const view = render(<SearchBlock kind="paths" truncated total={50} paths={['a', 'b']} />)
|
||||||
expect(view.getByText('已截断 · 共 50')).toBeTruthy()
|
expect(view.getByText('显示 2 / 共 50 个路径')).toBeTruthy()
|
||||||
|
expect(view.queryByText(/已截断/u)).toBeNull()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user