From cf18e1ca426eca210183ed864d2292392132778d Mon Sep 17 00:00:00 2001 From: Lachlan Campbell Date: Sun, 16 Jan 2022 18:09:46 -0500 Subject: [PATCH] feat(custom-properties): Warn in development on invalid theme keys --- packages/custom-properties/src/index.ts | 14 ++++++++++++++ packages/custom-properties/test/test.js | 16 ++++++++++++++-- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/packages/custom-properties/src/index.ts b/packages/custom-properties/src/index.ts index 1f40b6b7f..a5bafe1d0 100644 --- a/packages/custom-properties/src/index.ts +++ b/packages/custom-properties/src/index.ts @@ -1,6 +1,10 @@ import pluralize from 'pluralize' import { Theme } from '@theme-ui/css' +// Simplified validator based on spec https://www.w3.org/TR/CSS22/syndata.html#value-def-identifier +// Does not check for "cannot start with a digit, two hyphens, or a hyphen followed by a digit" +const keyValidator = /^[A-z0-9][\w-]*$/ + interface CustomProperties { [key: string]: string | number } @@ -12,6 +16,16 @@ export default function makeCustomProperties(theme: Theme, prefix?: string) { Object.entries(object).forEach(([key, value]) => { let formattedKey = pluralize(key, 1) + if ( + process.env.NODE_ENV !== 'production' && + !keyValidator.test(formattedKey) + ) { + console.warn( + `[theme-ui] Theme key "${value}" found will produce an invalid CSS custom property. ` + + 'Keys must only contain the following: A-Z, a-z, 0-9, hyphen, underscore.' + ) + } + if (prefix && !previousKey) { formattedKey = `${prefix}-${formattedKey}` } diff --git a/packages/custom-properties/test/test.js b/packages/custom-properties/test/test.js index 392a29c51..5f3523257 100644 --- a/packages/custom-properties/test/test.js +++ b/packages/custom-properties/test/test.js @@ -1,4 +1,5 @@ import toCustomProperties from '../src' +import mockConsole from 'jest-mock-console' const theme = { colors: { @@ -18,8 +19,7 @@ const theme = { }, }, fonts: { - body: - 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", sans-serif', + body: 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", sans-serif', heading: 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", sans-serif', monospace: 'Menlo, monospace', @@ -35,9 +35,11 @@ const theme = { } it('transforms a theme config to CSS custom properties', () => { + mockConsole() const result = toCustomProperties(theme) expect(result).toMatchSnapshot() + expect(console.warn).toHaveBeenCalledTimes(0) }) it('transforms a theme config to CSS custom properties with prefix', () => { @@ -45,3 +47,13 @@ it('transforms a theme config to CSS custom properties with prefix', () => { expect(result).toMatchSnapshot() }) + +it('warns on invalid CSS custom property key', () => { + mockConsole() + toCustomProperties({ sizes: { '1/4': 1 / 4, '1/2': 1 / 2 } }) + + expect(console.warn).toHaveBeenCalledTimes(2) + expect(console.warn).toHaveBeenLastCalledWith( + '[theme-ui] Theme key "0.5" found will produce an invalid CSS custom property. Keys must only contain the following: A-Z, a-z, 0-9, hyphen, underscore.' + ) +})