From 515a3b099091ac7e593e6b20e963ca07494162f2 Mon Sep 17 00:00:00 2001 From: osaton Date: Mon, 2 Dec 2024 12:38:03 +0200 Subject: [PATCH] Fix border collapsing when `borderStyle` changes --- src/reconciler.ts | 33 +++++++++++++++++++++++++++++++-- test/borders.tsx | 31 ++++++++++++++++++++++++++++++- 2 files changed, 61 insertions(+), 3 deletions(-) diff --git a/src/reconciler.ts b/src/reconciler.ts index 32e28d2d..29bde30d 100644 --- a/src/reconciler.ts +++ b/src/reconciler.ts @@ -95,6 +95,30 @@ type UpdatePayload = { style: Styles | undefined; }; +const finalizeChangedStyle = ( + changedStyle: Styles | undefined, + currentStyle: Styles | undefined, +): Styles | undefined => { + if (!changedStyle) { + return; + } + + if (!currentStyle) { + return changedStyle; + } + + const style = {...changedStyle}; + + if ('borderStyle' in style) { + style.borderTop = currentStyle.borderTop; + style.borderRight = currentStyle.borderRight; + style.borderBottom = currentStyle.borderBottom; + style.borderLeft = currentStyle.borderLeft; + } + + return style; +}; + export default createReconciler< ElementNames, Props, @@ -254,15 +278,20 @@ export default createReconciler< const props = diff(oldProps, newProps); - const style = diff( + const changedStyle = diff( oldProps['style'] as Styles, newProps['style'] as Styles, ); - if (!props && !style) { + if (!props && !changedStyle) { return null; } + const style = finalizeChangedStyle( + changedStyle as Styles, + newProps['style'] as Styles, + ); + return {props, style}; }, commitUpdate(node, {props, style}) { diff --git a/test/borders.tsx b/test/borders.tsx index 10a00ecf..9c8e9607 100644 --- a/test/borders.tsx +++ b/test/borders.tsx @@ -4,7 +4,7 @@ import boxen, {type Options} from 'boxen'; import indentString from 'indent-string'; import delay from 'delay'; import widestLine from 'widest-line'; -import cliBoxes from 'cli-boxes'; +import cliBoxes, {type Boxes} from 'cli-boxes'; import chalk from 'chalk'; import {render, Box, Text} from '../src/index.js'; import {renderToString} from './helpers/render-to-string.js'; @@ -613,6 +613,35 @@ test('hide all borders', t => { t.is(output, ['Above', 'Content', 'Below'].join('\n')); }); +test('keep borders hidden on `borderStyle` change', async t => { + const stdout = createStdout(); + + function Test() { + const [state, setState] = useState('single'); + + useEffect(() => { + setState('double'); + }, []); + + return ( + + Content + + ); + } + + render(, {stdout, debug: true}); + t.is((stdout.write as any).firstCall.args[0], 'Content'); + await delay(100); + t.is((stdout.write as any).lastCall.args[0], 'Content'); +}); + test('change color of top border', t => { const output = renderToString(