From 0e2426e414b36379b376314687b29b8df9134884 Mon Sep 17 00:00:00 2001 From: Steve Dodier-Lazaro Date: Thu, 12 Aug 2021 19:09:08 +0200 Subject: [PATCH] feat(classname): add support for arrays as modifier values --- packages/classname/README.md | 3 +++ packages/classname/classname.ts | 6 ++++- packages/classname/test/classname.test.ts | 30 +++++++++++++++++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/packages/classname/README.md b/packages/classname/README.md index a33d3989..e5c1f2b8 100644 --- a/packages/classname/README.md +++ b/packages/classname/README.md @@ -17,8 +17,11 @@ const cat = cn('Cat') cat() // Cat cat({ size: 'm' }) // Cat Cat_size_m +cat({ fur: ['short', 'black'] }) // Cat Cat_fur_short Cat_fur_black + cat('Tail') // Cat-Tail cat('Tail', { length: 'small' }) // Cat-Tail Cat-Tail_length_small +cat('Body', { fur: ['short', 'black'] }) // Cat-Body Cat-Body_fur_short Cat-Body_fur_black const dogPaw = cn('Dog', 'Paw') diff --git a/packages/classname/classname.ts b/packages/classname/classname.ts index f26c9998..72809597 100644 --- a/packages/classname/classname.ts +++ b/packages/classname/classname.ts @@ -8,7 +8,7 @@ export type ClassNameList = Array * * @see https://en.bem.info/methodology/key-concepts/#modifier */ -export type NoStrictEntityMods = Record +export type NoStrictEntityMods = Record /** * BEM Entity className initializer. @@ -84,6 +84,10 @@ export function withNaming(preset: Preset): ClassNameInitilizer { if (modVal === true) { className += modPrefix + k + } else if (Array.isArray(modVal)) { + for (let v = 0; v < modVal.length; v++) { + className += modPrefix + k + modValueDelimiter + modVal[v] + } } else if (modVal) { className += modPrefix + k + modValueDelimiter + modVal } diff --git a/packages/classname/test/classname.test.ts b/packages/classname/test/classname.test.ts index b5f84126..08476982 100644 --- a/packages/classname/test/classname.test.ts +++ b/packages/classname/test/classname.test.ts @@ -32,6 +32,15 @@ describe('@bem-react/classname', () => { expect(e(mods)).toEqual('Block-Elem Block-Elem_modName Block-Elem_modName2_modVal') }) + test('multi-valued mod', () => { + const mods = { modName: ['modValA', 'modValB'] } + const b = cn('Block') + const e = cn('Block', 'Elem') + + expect(b(mods)).toEqual('Block Block_modName_modValA Block_modName_modValB') + expect(e(mods)).toEqual('Block-Elem Block-Elem_modName_modValA Block-Elem_modName_modValB') + }) + test('empty', () => { const b = cn('Block') expect(b({})).toEqual('Block') @@ -91,6 +100,13 @@ describe('@bem-react/classname', () => { ) }) + test('carry elem with multi-valued mod', () => { + const b = cn('Block') + expect(b('Elem', { theme: ['normal', 'light'] }, ['Mix'])).toEqual( + 'Block-Elem Block-Elem_theme_normal Block-Elem_theme_light Mix', + ) + }) + test('undefined', () => { const b = cn('Block') expect(b('Elem', null, [undefined])).toEqual('Block-Elem') @@ -172,6 +188,17 @@ describe('@bem-react/classname', () => { expect(e(mods)).toEqual('block__elem block__elem_modName block__elem_modName2_modVal') }) + test('multi-valued mod', () => { + const mods = { modName: ['modValA', 'modValB'] } + const b = cCn('block') + const e = cCn('block', 'elem') + + expect(b(mods)).toEqual('block block_modName_modValA block_modName_modValB') + expect(e(mods)).toEqual( + 'block__elem block__elem_modName_modValA block__elem_modName_modValB', + ) + }) + test('empty', () => { const b = cCn('block') expect(b({})).toEqual('block') @@ -210,6 +237,9 @@ describe('@bem-react/classname', () => { expect(block('element', { mod: true })).toEqual('block__element block__element--mod') expect(block('element', { mod: false })).toEqual('block__element') expect(block('element', { mod: 'value' })).toEqual('block__element block__element--mod_value') + expect(block('element', { mod: ['valueA', 'valueB'] })).toEqual( + 'block__element block__element--mod_valueA block__element--mod_valueB', + ) }) })