mergeAttrs
Merges several { html, body } descriptors into React props: every class is kept once, and for other attributes the last value wins.
import { mergeAttrs } from '@salla.sa/twilight-theme-engine/tanstack';In plain words
When attributes come from more than one place, a layout and a page for example, mergeAttrs(layout, page) combines them in order. Classes add up. For any other attribute, such as data-theme, the later descriptor's value replaces the earlier one.
The result has the shape attrs() returns: htmlAttrs and bodyAttrs, with class renamed to className.
Signature
function mergeAttrs(...descriptors: DocumentElementDescriptor[]): {
htmlAttrs: Record<string, string>;
bodyAttrs: Record<string, string>;
}Try it live
mergeAttrs(layout, page): {…} 2 keys
bodyAttrs: {…} 2 keys
import { mergeAttrs } from '@salla.sa/twilight-theme-engine/tanstack';
const { bodyAttrs } = mergeAttrs(
{ body: { class: 'antialiased font-sans', 'data-theme': 'light' } },
{ body: { class: 'page-cart antialiased', 'data-theme': 'dark' } }
);
Example
import { mergeAttrs } from '@salla.sa/twilight-theme-engine/tanstack';
const layout = {
html: { class: 'antialiased' },
body: { class: 'font-sans', 'data-theme': 'light' },
};
const offersPage = { body: { class: 'page-offers', 'data-theme': 'dark' } };
export const { htmlAttrs, bodyAttrs } = mergeAttrs(layout, offersPage);
// htmlAttrs → { className: 'antialiased' }
// bodyAttrs → { 'data-theme': 'dark', className: 'font-sans page-offers' }
How it behaves
Descriptors are read left to right. Classes are collected in the order first seen; any other attribute takes the last non-empty string.
It is
mergeDocumentDescriptorsfrom/utilsunder a shorter name./nextjsexports the same function asmergeAttrs.
Gotchas
A later descriptor cannot remove an attribute: an empty string or
undefinedis skipped, so the earlier value stays. Leave the earlier descriptor out of the call instead.
Related
Turns an { html, body } attribute descriptor into React props to spread onto the html and body elements: class becomes className.
useAttrsCollects the html and body attributes the matched routes declare in staticData.documentAttrs, as React props for the root shell.
attrs, mergeAttrs (Next.js)The Next.js copies of attrs and mergeAttrs: descriptors in, htmlAttrs and bodyAttrs out, for a root layout that cannot call hooks.
mergeDocumentDescriptorsMerges several { html, body } attribute descriptors into React props for the html and body elements: classes combined, other attributes last-wins.