boxen icon indicating copy to clipboard operation
boxen copied to clipboard

Add `borderBackgroundColor` option

Open Caesarovich opened this issue 1 year ago • 5 comments

Hi,

I've added the borderBackgroundColor option, following most of @thornduke's implementation in #94. I've also added docs, example, test and types.

All tests pass except the xo that throws this error for pre-existing code:

  index.d.ts:9:5
  ✖   9:5   any overrides all other types in this intersection type.  @typescript-eslint/no-redundant-type-constituents
  ✖  42:5   any overrides all other types in this intersection type.  @typescript-eslint/no-redundant-type-constituents
  ✖  85:39  any overrides all other types in this union type.         @typescript-eslint/no-redundant-type-constituents

I'm not quite sure what triggers it, it might be a new error due to the recent dependency bump (see #97).

Also I'm wondering if we should make borderBackgroundColor default to backgroundColor if unspecified ?

closes #94

Caesarovich avatar Jul 16 '24 13:07 Caesarovich

Also I'm wondering if we should make borderBackgroundColor default to backgroundColor if unspecified ?

👍

sindresorhus avatar Jul 17 '24 11:07 sindresorhus

I've made it so that the user can specify 'none' for no color. I'm unsure if it's good or if we should use null instead.

Caesarovich avatar Jul 17 '24 14:07 Caesarovich

https://github.com/sindresorhus/boxen/pull/100#discussion_r1685533221

sindresorhus avatar May 27 '25 21:05 sindresorhus

AI review:


  • Don’t pollute the global Color type. You added 'none' to Color and then reused it for borderColor/backgroundColor, which wrongly allows 'none' there too. Revert 'none' from Color and restrict the sentinel to this one property only.

  • Drop 'none' here; use 'inherit' and presence instead. Follow the maintainer’s suggestion:

    • Omitted → inherit backgroundColor
    • 'inherit' → inherit backgroundColor
    • Explicit undefined (property present) → no BG color Update the runtime to check property presence and handle 'inherit' before validation. Types: borderBackgroundColor?: Exclude<Color, 'none'> | 'inherit'. ([GitHub][2])
  • Fix the validation/defaulting flow. Replace:

    options.borderBackgroundColor ??= options.backgroundColor;
    if (options.borderBackgroundColor === NONE) options.borderBackgroundColor = null;
    if (options.borderBackgroundColor && !isColorValid(...)) throw ...
    

    with:

    const hasBorderBG = Object.hasOwn(options, 'borderBackgroundColor');
    if (!hasBorderBG || options.borderBackgroundColor === 'inherit') {
    	options.borderBackgroundColor = options.backgroundColor;
    }
    if (options.borderBackgroundColor !== undefined && options.borderBackgroundColor !== options.backgroundColor) {
    	if (!isColorValid(options.borderBackgroundColor)) {
    		throw new Error(`${options.borderBackgroundColor} is not a valid borderBackgroundColor`);
    	}
    }
    

    and remove the NONE coupling entirely.

Must-fix (runtime behavior)

  • Unrelated margin coloring change. You moved marginLeft outside colorizeBorder for the top and bottom lines. That’s a behavioral change unrelated to this feature. Either revert it here or split it into its own PR with snapshots.
  • Don’t reuse the NONE constant. It’s a border-style sentinel; using it for a color sentinel is leaky and confusing. Remove that dependency.

Tests you’re missing

  • Inheritance cases. Add snapshots proving omitted and 'inherit' both pick up backgroundColor. Also add a case where the property is explicitly present but undefined → no BG color.
  • Dim interaction. Snapshot with {dimBorder: true, borderBackgroundColor: <color>} to ensure dimming doesn’t regress the BG application.
  • Conflict with content BG. {backgroundColor: 'blue', borderBackgroundColor: 'red'} and vice-versa. Multi-line content too.
  • Explicit invalids. Already added one invalid; keep it, and add one for 'inherit' being handled before validation (i.e., not throwing).

Docs & examples

  • README values. If you adopt 'inherit', document that and remove 'none'. Also keep color lists consistent with other options (gray/grey) and avoid duplicating long lists—reference the same set as backgroundColor.
  • Examples. Remove 'none' usage. Show both: inherited ('inherit') and explicit “no border BG” (property present but undefined) so users know how to opt out.
  • Types test. Replace the 'none' type test with 'inherit', and (optionally) include undefined to assert explicit opt-out compiles.

Nits

  • Order of color ops. Your colorizeBorder applies FG, then BG, then dim. That’s fine; just be intentional that dim won’t affect BG intensity in most terminals (desired for borders). No change required, just call it out in code comments.

sindresorhus avatar Sep 19 '25 03:09 sindresorhus

I will be extremely busy for the next 3 weeks. I'll have a look at all current Issues and PRs and plan the next move.

Caesarovich avatar Sep 20 '25 17:09 Caesarovich