From 632a0cb79bbc0aa80ef12ef66c0e2d39eee6c321 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sat, 13 Feb 2021 19:42:50 -0500 Subject: [PATCH] fix: issue where variants would sometimes apply only once --- .bin/build-watch.js | 13 +++++++++++++ .bin/test-watch.js | 13 +++++++++++++ package.json | 4 ++-- packages/core/src/index.js | 11 +++++++---- packages/core/tests/variants.js | 19 +++++++++++++++++++ 5 files changed, 54 insertions(+), 6 deletions(-) create mode 100644 .bin/build-watch.js create mode 100644 .bin/test-watch.js diff --git a/.bin/build-watch.js b/.bin/build-watch.js new file mode 100644 index 00000000..65ae45de --- /dev/null +++ b/.bin/build-watch.js @@ -0,0 +1,13 @@ +import nodemon from 'nodemon' +import process from 'process' + +nodemon( + [ + // prettier-ignore + `--watch packages/core/src`, + `--watch packages/core/tests`, + `--watch packages/react/src`, + `--watch packages/react/tests`, + `--exec "clear; ${['npm', 'run', 'build'].concat(process.argv.slice(2)).join(' ')}"`, + ].join(' '), +).on('quit', () => process.exit()) diff --git a/.bin/test-watch.js b/.bin/test-watch.js new file mode 100644 index 00000000..875fa4e8 --- /dev/null +++ b/.bin/test-watch.js @@ -0,0 +1,13 @@ +import nodemon from 'nodemon' +import process from 'process' + +nodemon( + [ + // prettier-ignore + `--watch packages/core/src`, + `--watch packages/core/tests`, + `--watch packages/react/src`, + `--watch packages/react/tests`, + `--exec "clear; ${['node', '.bin/test.js'].concat(process.argv.slice(2)).join(' ')}"`, + ].join(' '), +).on('quit', () => process.exit()) diff --git a/package.json b/package.json index 1537d753..50305779 100644 --- a/package.json +++ b/package.json @@ -7,14 +7,14 @@ "scripts": { "bootstrap": "lerna bootstrap --use-workspaces", "build": "node .bin/build", - "build:watch": "nodemon --watch packages/core/src --watch packages/core/tests --watch packages/react/src --watch packages/react/tests --exec \"clear; npm run build\"", + "build:watch": "node .bin/build-watch", "prerelease": "npm run build && npm run test", "release": "lerna publish", "release:canary": "npm run prerelease && lerna publish --dist-tag canary", "release:pack": "npm run prerelease && lerna exec -- npm pack", "postinstall": "run-s bootstrap", "test": "node .bin/test", - "test:watch": "nodemon --watch packages/core/src --watch packages/core/tests --watch packages/react/src --watch packages/react/tests --exec \"clear; npm run test\"" + "test:watch": "node .bin/test-watch" }, "workspaces": [ "packages/*", diff --git a/packages/core/src/index.js b/packages/core/src/index.js index 9b2a4e77..33d2b75f 100644 --- a/packages/core/src/index.js +++ b/packages/core/src/index.js @@ -194,12 +194,14 @@ const createCss = (init) => { if (condition != null) { if (!conditionVariants[condition]) { - const conditionalVariantClassName = (conditionVariants[condition] = variantClassName + '--' + getHashString('', condition)) + const conditionalVariantClassName = variantClassName + '--' + getHashString('', condition) const conditionalVariantCssText = getComputedCss({ [condition]: { ['.' + conditionalVariantClassName]: variantStyle } }) - variantRules.addCss(conditionalVariantCssText) - classNames.push(conditionalVariantClassName) + conditionVariants[condition] = [conditionalVariantCssText, conditionalVariantClassName] } + + variantRules.addCss(conditionVariants[condition][0]) + classNames.push(conditionVariants[condition][1]) } else { variantRules.addCss(variantCssText) } @@ -228,10 +230,11 @@ const createCss = (init) => { let expressClassNames = new Set(classNames()) - for (const propName in defaultVariants) + for (const propName in defaultVariants) { if (!(propName in props) && propName in variants) { props[propName] = defaultVariants[propName] } + } if (classProp in props) { String(props[classProp]).split(/\s+/).forEach(expressClassNames.add, expressClassNames) diff --git a/packages/core/tests/variants.js b/packages/core/tests/variants.js index 1e102fdc..dd1bbd1d 100644 --- a/packages/core/tests/variants.js +++ b/packages/core/tests/variants.js @@ -277,4 +277,23 @@ describe('Conditional variants', () => { expect(component({ size: { bp1: 'small', bp2: 'large' } }).className).toBe([componentClassName, componentSmallBp1ClassName, componentLargeBp2ClassName].join(' ')) expect(toString()).toBe([componentSmallBp1CssText, componentLargeBp2CssText].join('')) }) + + test('Renders a component with a conditional variant repeatedly', () => { + const { css, toString } = createCss(config) + const component = css(componentConfig) + const componentClassName = `sx03kze` + const componentSmallBp1ClassName = `${componentClassName}tmy8g--size-small--5m2l7` + const componentLargeBp2ClassName = `${componentClassName}fhyhx--size-large--8c3r4` + const componentSmallBp1CssText = `@media (max-width: 767px){.${componentSmallBp1ClassName}{font-size:16px;}}` + const componentLargeBp2CssText = `@media (min-width: 768px){.sx03kzefhyhx--size-large--8c3r4{font-size:24px;}}` + + expect(component({ size: { bp1: 'small', bp2: 'large' } }).className).toBe([componentClassName, componentSmallBp1ClassName, componentLargeBp2ClassName].join(' ')) + expect(toString()).toBe([componentSmallBp1CssText, componentLargeBp2CssText].join('')) + + expect(component({ size: { bp1: 'small', bp2: 'large' } }).className).toBe([componentClassName, componentSmallBp1ClassName, componentLargeBp2ClassName].join(' ')) + expect(toString()).toBe([componentSmallBp1CssText, componentLargeBp2CssText].join('')) + + expect(component({ size: { bp1: 'small', bp2: 'large' } }).className).toBe([componentClassName, componentSmallBp1ClassName, componentLargeBp2ClassName].join(' ')) + expect(toString()).toBe([componentSmallBp1CssText, componentLargeBp2CssText].join('')) + }) })