From 24bf8278d53907027bf89378ccec4632c0a6c542 Mon Sep 17 00:00:00 2001 From: el-makarova Date: Fri, 12 Jan 2024 11:33:09 +0300 Subject: [PATCH] feat: calculate initial body classes in @gravity-ui/uikit notation if `theme` property is provided --- README.md | 3 +++ src/render.test.ts | 25 +++++++++++++++++++++++++ src/render.ts | 17 ++++++++++++++++- src/types.ts | 1 + 4 files changed, 45 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f4ca7ef..d737d9c 100644 --- a/README.md +++ b/README.md @@ -67,6 +67,8 @@ interface RenderParams { // content of body tag bodyContent?: { + // initial application theme if @gravity-ui/uikit is used + theme?: string; // class name for body tag className?: string; // body content before div tag with id root @@ -252,6 +254,7 @@ interface RenderContent { inlineScripts: string[]; inlineStyleSheets: string[]; bodyContent: { + theme?: string; className: string[]; beforeRoot: string[]; root?: string; diff --git a/src/render.test.ts b/src/render.test.ts index 521e979..da5aad8 100644 --- a/src/render.test.ts +++ b/src/render.test.ts @@ -21,3 +21,28 @@ test('should render root content', () => { /
\s*content\s*<\/div>/, ); }); + +test('should render body classes', () => { + expect( + createRenderFunction()({ + title: 'Foobar', + bodyContent: {root: 'content', className: 'test'}, + }), + ).toMatch(/\s*
\s*content\s*<\/div>\s*<\/body>/); + expect( + createRenderFunction()({ + title: 'Foobar', + bodyContent: {root: 'content', theme: 'light'}, + }), + ).toMatch( + /\s*
\s*content\s*<\/div>\s*<\/body>/, + ); + expect( + createRenderFunction()({ + title: 'Foobar', + bodyContent: {root: 'content', className: 'test', theme: 'light'}, + }), + ).toMatch( + /\s*
\s*content\s*<\/div>\s*<\/body>/, + ); +}); diff --git a/src/render.ts b/src/render.ts index b3b1335..bbe52ac 100644 --- a/src/render.ts +++ b/src/render.ts @@ -2,6 +2,17 @@ import htmlescape from 'htmlescape'; import {attrs, getRenderHelpers, hasProperty} from './utils.js'; import type {Icon, Meta, RenderParams, Plugin, RenderContent} from './types.js'; +function getRootClassName(theme?: string) { + if (!theme) { + return []; + } + const classes = ['g-root']; + if (theme) { + classes.push(`g-root_theme_${theme}`); + } + return classes; +} + const defaultIcon: Icon = { type: 'image/png', sizes: '16x16', @@ -37,8 +48,12 @@ export function generateRenderContent( inlineScripts.unshift(`window.__DATA__ = ${htmlescape(params.data || {})};`); const content = params.bodyContent ?? {}; + const {theme, className} = content; + const bodyClasses = Array.from( + new Set([...getRootClassName(theme), ...(className ? className.split(' ') : [])]), + ); const bodyContent = { - className: content.className ? [content.className] : [], + className: bodyClasses, root: content.root, beforeRoot: content.beforeRoot ? [content.beforeRoot] : [], afterRoot: content.afterRoot ? [content.afterRoot] : [], diff --git a/src/types.ts b/src/types.ts index 936f2d5..470fa93 100644 --- a/src/types.ts +++ b/src/types.ts @@ -80,6 +80,7 @@ export interface RenderParams extends Commo inlineScripts?: string[]; inlineStyleSheets?: string[]; bodyContent?: { + theme?: string; className?: string; beforeRoot?: string; root?: string;