Skip to content

Commit 456b8bd

Browse files
Improve split border colour clarity
1 parent 69fc0f1 commit 456b8bd

2 files changed

Lines changed: 27 additions & 8 deletions

File tree

src/__tests__/components/PhraseBox.test.tsx

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ describe('PhraseBox', () => {
249249
expect(screen.getByTestId('token-token-2')).toHaveAttribute('data-split-free', 'true');
250250
});
251251

252-
it('reddens the whole box (not individual chips) when every token would become free', () => {
252+
it('reddens both chips (not the box) for a multi-token box where every token would become free', () => {
253253
render(
254254
<AnalysisStoreProvider analysisLanguage="und">
255255
<PhraseBox
@@ -260,12 +260,30 @@ describe('PhraseBox', () => {
260260
</AnalysisStoreProvider>,
261261
);
262262

263-
// A fully-free box (e.g. a single-token fragment) reddens at the box level; per-chip flagging is
264-
// suppressed so the border isn't drawn twice.
263+
// A 2-token phrase splits into two free tokens; each is shown on its own chip, never as a
264+
// whole-box border (that would draw a single border around both rather than per token).
265+
const phraseBox = document.querySelector('[data-phrase-box="true"]');
266+
expect(phraseBox).not.toHaveClass('tw:border-destructive');
267+
expect(screen.getByTestId('token-token-1')).toHaveAttribute('data-split-free', 'true');
268+
expect(screen.getByTestId('token-token-2')).toHaveAttribute('data-split-free', 'true');
269+
});
270+
271+
it('reddens the whole box (not the chip) for a lone single-token fragment that would become free', () => {
272+
render(
273+
<AnalysisStoreProvider analysisLanguage="und">
274+
<PhraseBox
275+
{...requiredProps()}
276+
tokens={[TEST_TOKEN]}
277+
splitFreeTokenRefs={new Set(['token-1'])}
278+
/>
279+
</AnalysisStoreProvider>,
280+
);
281+
282+
// A single-token fragment (e.g. one run of a discontiguous phrase) reddens at the box level;
283+
// per-chip flagging is suppressed so the border isn't drawn twice.
265284
const phraseBox = document.querySelector('[data-phrase-box="true"]');
266285
expect(phraseBox).toHaveClass('tw:border-destructive');
267286
expect(screen.getByTestId('token-token-1')).toHaveAttribute('data-split-free', 'false');
268-
expect(screen.getByTestId('token-token-2')).toHaveAttribute('data-split-free', 'false');
269287
});
270288

271289
it('phrase box does not override cursor on gap areas', () => {

src/components/PhraseBox.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -314,10 +314,11 @@ export function PhraseBox({
314314

315315
const isRealPhrase = phraseLink !== undefined;
316316

317-
// The whole box previews as becoming free only when every token in it would. A single-token
318-
// fragment reddens its box; a multi-token contiguous box reddens only the affected chips below.
319-
const isBoxSplitFree =
320-
splitFreeTokenRefs !== undefined && tokens.every((t) => splitFreeTokenRefs.has(t.ref));
317+
// The whole box previews as becoming free only when it is a lone single-token fragment that would
318+
// be freed (e.g. a one-token run of a discontiguous phrase). A multi-token box always reddens the
319+
// affected chips individually below, even when every token would be freed (a 2-token phrase
320+
// splits into two free tokens, but each is shown on its own chip rather than as a box).
321+
const isBoxSplitFree = tokens.length === 1 && (splitFreeTokenRefs?.has(tokens[0].ref) ?? false);
321322

322323
// --- view mode ---
323324
if (phraseMode.kind === 'view') {

0 commit comments

Comments
 (0)