Skip to content

Commit

Permalink
Fix (core): makeTheme should perform deep merges of objects
Browse files Browse the repository at this point in the history
  • Loading branch information
SBoudrias committed May 11, 2024
1 parent 12b0617 commit 6c397a3
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 6 deletions.
4 changes: 1 addition & 3 deletions packages/checkbox/src/index.mts
Expand Up @@ -103,9 +103,7 @@ export default createPrompt(
required,
validate = () => true,
} = config;
const theme = makeTheme<CheckboxTheme>(checkboxTheme, config.theme, {
icon: Object.assign({}, checkboxTheme.icon, config.theme?.icon),
});
const theme = makeTheme<CheckboxTheme>(checkboxTheme, config.theme);
const prefix = usePrefix({ theme });
const firstRender = useRef(true);
const [status, setStatus] = useState('pending');
Expand Down
37 changes: 34 additions & 3 deletions packages/core/src/lib/make-theme.mts
@@ -1,10 +1,41 @@
import type { Prettify, PartialDeep } from '@inquirer/type';
import { defaultTheme, type Theme } from './theme.mjs';

function isPlainObject(value: unknown): value is object {
if (typeof value !== 'object' || value === null) return false;

let proto = value;
while (Object.getPrototypeOf(proto) !== null) {
proto = Object.getPrototypeOf(proto);
}

return Object.getPrototypeOf(value) === proto;
}

function deepMerge<T extends object>(...objects: Partial<T>[]): T {
const output: { [key: string]: unknown } = {};

for (const obj of objects) {
for (const [key, value] of Object.entries(obj)) {
const prevValue = output[key] as unknown;

if (isPlainObject(prevValue) && isPlainObject(value)) {

Check failure on line 22 in packages/core/src/lib/make-theme.mts

View workflow job for this annotation

GitHub Actions / Linting

This `if` statement can be replaced by a ternary expression
output[key] = deepMerge(prevValue, value);
} else {
output[key] = value;
}
}
}

return output as T;
}

export function makeTheme<SpecificTheme extends object>(
...themes: ReadonlyArray<undefined | PartialDeep<Theme<SpecificTheme>>>
): Prettify<Theme<SpecificTheme>> {
return Object.assign({}, defaultTheme, ...themes, {
style: Object.assign({}, defaultTheme.style, ...themes.map((theme) => theme?.style)),
});
const themesToMerge = [
defaultTheme,
...themes.filter((theme) => theme != null),
] as Theme<SpecificTheme>[];
return deepMerge(...themesToMerge);
}

0 comments on commit 6c397a3

Please sign in to comment.