From 65637031aa286f4493f5bd0145a1bf49893ff6c0 Mon Sep 17 00:00:00 2001 From: Nick Randall Date: Tue, 24 Aug 2021 10:16:59 -0600 Subject: [PATCH 1/9] feat(createGlobalThemeContract): implement and add tests --- .../css/src/__snapshots__/vars.test.ts.snap | 31 ++++++++ packages/css/src/vars.test.ts | 70 ++++++++++++++++++- packages/css/src/vars.ts | 36 ++++++++++ 3 files changed, 136 insertions(+), 1 deletion(-) create mode 100644 packages/css/src/__snapshots__/vars.test.ts.snap diff --git a/packages/css/src/__snapshots__/vars.test.ts.snap b/packages/css/src/__snapshots__/vars.test.ts.snap new file mode 100644 index 000000000..46901559a --- /dev/null +++ b/packages/css/src/__snapshots__/vars.test.ts.snap @@ -0,0 +1,31 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`createGlobalThemeContract supports adding a prefix 1`] = ` +Object { + "color": Object { + "blue": "var(--prefix-color-blue)", + "green": "var(--prefix-color-green)", + "red": "var(--prefix-color-red)", + }, +} +`; + +exports[`createGlobalThemeContract supports defining css vars via object properties 1`] = ` +Object { + "color": Object { + "blue": "var(--color-blue)", + "green": "var(--color-green)", + "red": "var(--color-red)", + }, +} +`; + +exports[`createGlobalThemeContract supports path based names 1`] = ` +Object { + "color": Object { + "blue": "var(--prefix-color-blue)", + "green": "var(--prefix-color-green)", + "red": "var(--prefix-color-red)", + }, +} +`; diff --git a/packages/css/src/vars.test.ts b/packages/css/src/vars.test.ts index 57b41c48e..6e65eba2b 100644 --- a/packages/css/src/vars.test.ts +++ b/packages/css/src/vars.test.ts @@ -1,4 +1,4 @@ -import { fallbackVar } from './vars'; +import { fallbackVar, createGlobalThemeContract } from './vars'; describe('fallbackVar', () => { it('supports a single string fallback', () => { @@ -67,3 +67,71 @@ describe('fallbackVar', () => { }).toThrowErrorMatchingInlineSnapshot(`"Invalid variable name: INVALID"`); }); }); + +describe('createGlobalThemeContract', () => { + it('supports defining css vars via object properties', () => { + expect( + createGlobalThemeContract({ + color: { + red: 'color-red', + blue: 'color-blue', + green: 'color-green', + }, + }), + ).toMatchSnapshot(); + }); + it('supports adding a prefix', () => { + expect( + createGlobalThemeContract( + { + color: { + red: 'color-red', + blue: 'color-blue', + green: 'color-green', + }, + }, + (value) => `prefix-${value}`, + ), + ).toMatchSnapshot(); + }); + it('supports path based names', () => { + expect( + createGlobalThemeContract( + { + color: { + red: null, + blue: null, + green: null, + }, + }, + (_, path) => `prefix-${path.join('-')}`, + ), + ).toMatchSnapshot(); + }); + it('errors when invalid property value', () => { + expect(() => + createGlobalThemeContract({ + color: { + red: null, + blue: null, + green: null, + }, + }), + ).toThrow(); + }); + it('errors when invalid map value', () => { + expect(() => + createGlobalThemeContract( + { + color: { + red: 'color-red', + blue: 'color-blue', + green: 'color-green', + }, + }, + // @ts-expect-error + () => null, + ), + ).toThrow(); + }); +}); diff --git a/packages/css/src/vars.ts b/packages/css/src/vars.ts index 90e5a38b1..8956cc03a 100644 --- a/packages/css/src/vars.ts +++ b/packages/css/src/vars.ts @@ -76,3 +76,39 @@ export function createThemeContract( return createVar(path.join('-')); }); } + +export type MapValue = string | null | undefined; +export type Mapper = (value: MapValue, path: Array) => string; +const defaultMapper: Mapper = (value, path) => { + if (typeof value !== 'string') { + throw new Error( + `To use the default map function with "createGlobalThemeContract", each property value must be a string. Property "${path.join( + '.', + )}"'s value is "${value}".`, + ); + } + return value; +}; + +export function createGlobalThemeContract< + ThemeTokens extends NullableTokens, +>( + tokens: ThemeTokens, + map: Mapper = defaultMapper, +): ThemeVars { + return walkObject(tokens, (value, path) => { + const varName = map(value as MapValue, path); + if (typeof varName !== 'string') { + throw new Error( + `The map function used by "createGlobalThemeContract" must return a string and instead returned "${value}".`, + ); + } + const cssVarName = cssesc( + varName.match(/^[0-9]/) ? `_${varName}` : varName, + { + isIdentifier: true, + }, + ); + return `var(--${cssVarName})` as const; + }); +} From e5aa3a63fa0f77b3e4da864f363b6c053e1f6333 Mon Sep 17 00:00:00 2001 From: Nick Randall Date: Tue, 24 Aug 2021 10:39:00 -0600 Subject: [PATCH 2/9] feat(createGlobalThemeContract): format and fix tests --- packages/css/src/vars.ts | 10 ++++------ packages/private/src/index.ts | 1 + packages/private/src/walkObject.ts | 2 +- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/packages/css/src/vars.ts b/packages/css/src/vars.ts index 8956cc03a..428ab5767 100644 --- a/packages/css/src/vars.ts +++ b/packages/css/src/vars.ts @@ -4,6 +4,7 @@ import { Contract, MapLeafNodes, CSSVarFunction, + Primitive, } from '@vanilla-extract/private'; import hash from '@emotion/hash'; import cssesc from 'cssesc'; @@ -77,8 +78,7 @@ export function createThemeContract( }); } -export type MapValue = string | null | undefined; -export type Mapper = (value: MapValue, path: Array) => string; +export type Mapper = (value: Primitive, path: Array) => string; const defaultMapper: Mapper = (value, path) => { if (typeof value !== 'string') { throw new Error( @@ -90,14 +90,12 @@ const defaultMapper: Mapper = (value, path) => { return value; }; -export function createGlobalThemeContract< - ThemeTokens extends NullableTokens, ->( +export function createGlobalThemeContract( tokens: ThemeTokens, map: Mapper = defaultMapper, ): ThemeVars { return walkObject(tokens, (value, path) => { - const varName = map(value as MapValue, path); + const varName = map(value, path); if (typeof varName !== 'string') { throw new Error( `The map function used by "createGlobalThemeContract" must return a string and instead returned "${value}".`, diff --git a/packages/private/src/index.ts b/packages/private/src/index.ts index 86a6fb1a9..51a4a856c 100644 --- a/packages/private/src/index.ts +++ b/packages/private/src/index.ts @@ -2,3 +2,4 @@ export type { Contract, MapLeafNodes, CSSVarFunction } from './types'; export { getVarName } from './getVarName'; export { get } from './get'; export { walkObject } from './walkObject'; +export type { Primitive } from './walkObject'; diff --git a/packages/private/src/walkObject.ts b/packages/private/src/walkObject.ts index 09983953d..a1257b93b 100644 --- a/packages/private/src/walkObject.ts +++ b/packages/private/src/walkObject.ts @@ -1,6 +1,6 @@ import { MapLeafNodes } from './types'; -type Primitive = string | number | null | undefined; +export type Primitive = string | number | null | undefined; type Walkable = { [Key in string | number]: Primitive | Walkable; From 1bb5f128b437a1a158eac4dde111353ee821301c Mon Sep 17 00:00:00 2001 From: Mark Dalgleish Date: Fri, 27 Aug 2021 09:24:40 +1000 Subject: [PATCH 3/9] Add changeset --- .changeset/shiny-bees-rest.md | 77 +++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 .changeset/shiny-bees-rest.md diff --git a/.changeset/shiny-bees-rest.md b/.changeset/shiny-bees-rest.md new file mode 100644 index 000000000..26337d44d --- /dev/null +++ b/.changeset/shiny-bees-rest.md @@ -0,0 +1,77 @@ +--- +'@vanilla-extract/css': minor +--- + +Add `createGlobalThemeContract` function + +Creates a contract of globally scoped variable names for themes to implement. + +> 💡 This is useful if you want to make your theme contract available to non-JavaScript environments. + +```ts +// themes.css.ts +import { + createGlobalThemeContract, + createGlobalTheme +} from '@vanilla-extract/css'; +export const vars = createGlobalThemeContract({ + color: { + brand: 'ui-color-brand' + }, + font: { + body: 'ui-font-body' + } +}); +createGlobalTheme(':root', vars, { + color: { + brand: 'blue' + }, + font: { + body: 'arial' + } +}); +``` + +You can also provide a map function as the second argument which has access to the value and the object path. + +For example, you can automatically prefix all variable names. + +```ts +// themes.css.ts +import { + createGlobalThemeContract, + createGlobalTheme +} from '@vanilla-extract/css'; +export const vars = createGlobalThemeContract( + { + color: { + brand: 'color-brand' + }, + font: { + body: 'font-body' + } + }, + (value) => `ui-${value}` +); +``` + +You can also use the map function to automatically generate names from the object path, joining keys with a hyphen. + +```ts +// themes.css.ts +import { + createGlobalThemeContract, + createGlobalTheme +} from '@vanilla-extract/css'; +export const vars = createGlobalThemeContract( + { + color: { + brand: null + }, + font: { + body: null + } + }, + (_value, path) => path.join('-') +); +``` \ No newline at end of file From 3dfb9d02e859ba2dad64b608cfe39256ef02f533 Mon Sep 17 00:00:00 2001 From: Mark Dalgleish Date: Fri, 27 Aug 2021 09:36:49 +1000 Subject: [PATCH 4/9] Add docs --- README.md | 79 +++++++++++++++++++++++++++++- site/docs/styling-api.md | 80 ++++++++++++++++++++++++++++++- site/src/DocsPage/DocsPage.css.ts | 2 +- 3 files changed, 157 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index f33237ca8..7250fefa3 100644 --- a/README.md +++ b/README.md @@ -581,7 +581,7 @@ createGlobalTheme(':root', vars, { ### createThemeContract -Creates a contract for themes to implement. +Creates a contract of locally scoped variable names for themes to implement. **Ensure this function is called within a `.css.ts` context, otherwise variable names will be mismatched between files.** @@ -623,6 +623,81 @@ export const themeB = createTheme(vars, { }); ``` +### createGlobalThemeContract + +Creates a contract of globally scoped variable names for themes to implement. + +> 💡 This is useful if you want to make your theme contract available to non-JavaScript environments. + +```ts +// themes.css.ts + +import { + createGlobalThemeContract, + createGlobalTheme +} from '@vanilla-extract/css'; + +export const vars = createGlobalThemeContract({ + color: { + brand: 'ui-color-brand' + }, + font: { + body: 'ui-font-body' + } +}); + +createGlobalTheme(':root', vars, { + color: { + brand: 'blue' + }, + font: { + body: 'arial' + } +}); +``` + +You can also provide a map function as the second argument which has access to the value and the object path. + +For example, you can automatically prefix all variable names. + +```ts +// themes.css.ts + +import { + createGlobalThemeContract, + createGlobalTheme +} from '@vanilla-extract/css'; + +export const vars = createGlobalThemeContract({ + color: { + brand: 'color-brand' + }, + font: { + body: 'font-body' + } +}, (value) => `ui-${value}`); +``` + +You can also use the map function to automatically generate names from the object path, joining keys with a hyphen. + +```ts +// themes.css.ts + +import { + createGlobalThemeContract, + createGlobalTheme +} from '@vanilla-extract/css'; + +export const vars = createGlobalThemeContract({ + color: { + brand: null + }, + font: { + body: null + } +}, (_value, path) => path.join('-')); +``` + ### assignVars Assigns a collection of CSS Variables anywhere within a style block. @@ -938,4 +1013,4 @@ const styles = { ## License -MIT. +MIT. \ No newline at end of file diff --git a/site/docs/styling-api.md b/site/docs/styling-api.md index 56a06c46e..e70eec922 100644 --- a/site/docs/styling-api.md +++ b/site/docs/styling-api.md @@ -293,7 +293,7 @@ createGlobalTheme(':root', vars, { ## createThemeContract -Creates a contract for themes to implement. +Creates a contract of locally scoped variable names for themes to implement. **Ensure this function is called within a `.css.ts` context, otherwise variable names will be mismatched between files.** @@ -334,6 +334,84 @@ export const themeB = createTheme(vars, { }); ``` +## createGlobalThemeContract + +Creates a contract of globally scoped variable names for themes to implement. + +> 💡 This is useful if you want to make your theme contract available to non-JavaScript environments. + +```ts +// themes.css.ts +import { + createGlobalThemeContract, + createGlobalTheme +} from '@vanilla-extract/css'; + +export const vars = createGlobalThemeContract({ + color: { + brand: 'ui-color-brand' + }, + font: { + body: 'ui-font-body' + } +}); + +createGlobalTheme(':root', vars, { + color: { + brand: 'blue' + }, + font: { + body: 'arial' + } +}); +``` + +You can also provide a map function as the second argument which has access to the value and the object path. + +For example, you can automatically prefix all variable names. + +```ts +// themes.css.ts +import { + createGlobalThemeContract, + createGlobalTheme +} from '@vanilla-extract/css'; + +export const vars = createGlobalThemeContract( + { + color: { + brand: 'color-brand' + }, + font: { + body: 'font-body' + } + }, + (value) => `ui-${value}` +); +``` + +You can also use the map function to automatically generate names from the object path, joining keys with a hyphen. + +```ts +// themes.css.ts +import { + createGlobalThemeContract, + createGlobalTheme +} from '@vanilla-extract/css'; + +export const vars = createGlobalThemeContract( + { + color: { + brand: null + }, + font: { + body: null + } + }, + (_value, path) => path.join('-') +); +``` + ## assignVars Assigns a collection of CSS Variables anywhere within a style block. diff --git a/site/src/DocsPage/DocsPage.css.ts b/site/src/DocsPage/DocsPage.css.ts index 77fd38fe1..faad9f6a2 100644 --- a/site/src/DocsPage/DocsPage.css.ts +++ b/site/src/DocsPage/DocsPage.css.ts @@ -4,7 +4,7 @@ import { vars } from '../themes.css'; import { responsiveStyle } from '../themeUtils'; const headerHeight = '90px'; -const sidebarWidth = '265px'; +const sidebarWidth = '300px'; export const bodyLock = style({ overflow: 'hidden!important', From c5bc3a821fa7d67b39088aad3195d06b0dbbcd2d Mon Sep 17 00:00:00 2001 From: Mark Dalgleish Date: Fri, 27 Aug 2021 09:41:22 +1000 Subject: [PATCH 5/9] Switch to inline snapshots --- .../css/src/__snapshots__/vars.test.ts.snap | 31 ------------------- packages/css/src/vars.test.ts | 30 ++++++++++++++++-- 2 files changed, 27 insertions(+), 34 deletions(-) delete mode 100644 packages/css/src/__snapshots__/vars.test.ts.snap diff --git a/packages/css/src/__snapshots__/vars.test.ts.snap b/packages/css/src/__snapshots__/vars.test.ts.snap deleted file mode 100644 index 46901559a..000000000 --- a/packages/css/src/__snapshots__/vars.test.ts.snap +++ /dev/null @@ -1,31 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`createGlobalThemeContract supports adding a prefix 1`] = ` -Object { - "color": Object { - "blue": "var(--prefix-color-blue)", - "green": "var(--prefix-color-green)", - "red": "var(--prefix-color-red)", - }, -} -`; - -exports[`createGlobalThemeContract supports defining css vars via object properties 1`] = ` -Object { - "color": Object { - "blue": "var(--color-blue)", - "green": "var(--color-green)", - "red": "var(--color-red)", - }, -} -`; - -exports[`createGlobalThemeContract supports path based names 1`] = ` -Object { - "color": Object { - "blue": "var(--prefix-color-blue)", - "green": "var(--prefix-color-green)", - "red": "var(--prefix-color-red)", - }, -} -`; diff --git a/packages/css/src/vars.test.ts b/packages/css/src/vars.test.ts index 6e65eba2b..6e8844ed8 100644 --- a/packages/css/src/vars.test.ts +++ b/packages/css/src/vars.test.ts @@ -78,7 +78,15 @@ describe('createGlobalThemeContract', () => { green: 'color-green', }, }), - ).toMatchSnapshot(); + ).toMatchInlineSnapshot(` + Object { + "color": Object { + "blue": "var(--color-blue)", + "green": "var(--color-green)", + "red": "var(--color-red)", + }, + } + `); }); it('supports adding a prefix', () => { expect( @@ -92,7 +100,15 @@ describe('createGlobalThemeContract', () => { }, (value) => `prefix-${value}`, ), - ).toMatchSnapshot(); + ).toMatchInlineSnapshot(` + Object { + "color": Object { + "blue": "var(--prefix-color-blue)", + "green": "var(--prefix-color-green)", + "red": "var(--prefix-color-red)", + }, + } + `); }); it('supports path based names', () => { expect( @@ -106,7 +122,15 @@ describe('createGlobalThemeContract', () => { }, (_, path) => `prefix-${path.join('-')}`, ), - ).toMatchSnapshot(); + ).toMatchInlineSnapshot(` + Object { + "color": Object { + "blue": "var(--prefix-color-blue)", + "green": "var(--prefix-color-green)", + "red": "var(--prefix-color-red)", + }, + } + `); }); it('errors when invalid property value', () => { expect(() => From 94ac6228ae1258777807790d550df4a18f311f52 Mon Sep 17 00:00:00 2001 From: Mark Dalgleish Date: Fri, 27 Aug 2021 10:41:12 +1000 Subject: [PATCH 6/9] Tweak logic, update tests --- .changeset/shiny-bees-rest.md | 4 +++ packages/css/src/vars.test.ts | 45 +++++++++++++++++++++++++--- packages/css/src/vars.ts | 48 ++++++++++++++---------------- packages/private/src/index.ts | 1 - packages/private/src/walkObject.ts | 2 +- 5 files changed, 68 insertions(+), 32 deletions(-) diff --git a/.changeset/shiny-bees-rest.md b/.changeset/shiny-bees-rest.md index 26337d44d..3c4453744 100644 --- a/.changeset/shiny-bees-rest.md +++ b/.changeset/shiny-bees-rest.md @@ -14,6 +14,7 @@ import { createGlobalThemeContract, createGlobalTheme } from '@vanilla-extract/css'; + export const vars = createGlobalThemeContract({ color: { brand: 'ui-color-brand' @@ -22,6 +23,7 @@ export const vars = createGlobalThemeContract({ body: 'ui-font-body' } }); + createGlobalTheme(':root', vars, { color: { brand: 'blue' @@ -42,6 +44,7 @@ import { createGlobalThemeContract, createGlobalTheme } from '@vanilla-extract/css'; + export const vars = createGlobalThemeContract( { color: { @@ -63,6 +66,7 @@ import { createGlobalThemeContract, createGlobalTheme } from '@vanilla-extract/css'; + export const vars = createGlobalThemeContract( { color: { diff --git a/packages/css/src/vars.test.ts b/packages/css/src/vars.test.ts index 6e8844ed8..c9ee173b4 100644 --- a/packages/css/src/vars.test.ts +++ b/packages/css/src/vars.test.ts @@ -88,6 +88,7 @@ describe('createGlobalThemeContract', () => { } `); }); + it('supports adding a prefix', () => { expect( createGlobalThemeContract( @@ -110,6 +111,7 @@ describe('createGlobalThemeContract', () => { } `); }); + it('supports path based names', () => { expect( createGlobalThemeContract( @@ -132,17 +134,50 @@ describe('createGlobalThemeContract', () => { } `); }); + it('errors when invalid property value', () => { expect(() => createGlobalThemeContract({ color: { + // @ts-expect-error red: null, - blue: null, - green: null, + blue: 'color-blue', + green: 'color-green', + }, + }), + ).toThrowErrorMatchingInlineSnapshot( + `"Invalid variable name for \\"color.red\\": null"`, + ); + }); + + it('errors when escaped property value', () => { + expect(() => + createGlobalThemeContract({ + color: { + red: 'color-red', + blue: "color'blue", + green: 'color-green', + }, + }), + ).toThrowErrorMatchingInlineSnapshot( + `"Invalid variable name for \\"color.blue\\": color'blue"`, + ); + }); + + it('errors when property value starts with a number', () => { + expect(() => + createGlobalThemeContract({ + color: { + red: 'color-red', + blue: 'color-blue', + green: '123-color-green', }, }), - ).toThrow(); + ).toThrowErrorMatchingInlineSnapshot( + `"Invalid variable name for \\"color.green\\": 123-color-green"`, + ); }); + it('errors when invalid map value', () => { expect(() => createGlobalThemeContract( @@ -156,6 +191,8 @@ describe('createGlobalThemeContract', () => { // @ts-expect-error () => null, ), - ).toThrow(); + ).toThrowErrorMatchingInlineSnapshot( + `"Invalid variable name for \\"color.red\\": null"`, + ); }); }); diff --git a/packages/css/src/vars.ts b/packages/css/src/vars.ts index 428ab5767..2064f6ef8 100644 --- a/packages/css/src/vars.ts +++ b/packages/css/src/vars.ts @@ -4,12 +4,11 @@ import { Contract, MapLeafNodes, CSSVarFunction, - Primitive, } from '@vanilla-extract/private'; import hash from '@emotion/hash'; import cssesc from 'cssesc'; -import { NullableTokens, ThemeVars } from './types'; +import { Tokens, NullableTokens, ThemeVars } from './types'; import { getAndIncrementRefCounter, getFileScope } from './fileScope'; import { validateContract } from './validateContract'; @@ -78,35 +77,32 @@ export function createThemeContract( }); } -export type Mapper = (value: Primitive, path: Array) => string; -const defaultMapper: Mapper = (value, path) => { - if (typeof value !== 'string') { - throw new Error( - `To use the default map function with "createGlobalThemeContract", each property value must be a string. Property "${path.join( - '.', - )}"'s value is "${value}".`, - ); - } - return value; -}; - +export function createGlobalThemeContract( + tokens: ThemeTokens, +): ThemeVars; export function createGlobalThemeContract( tokens: ThemeTokens, - map: Mapper = defaultMapper, -): ThemeVars { + mapFn: (value: string | null, path: Array) => string, +): ThemeVars; +export function createGlobalThemeContract( + tokens: Tokens | NullableTokens, + mapFn?: (value: string | null, path: Array) => string, +) { return walkObject(tokens, (value, path) => { - const varName = map(value, path); - if (typeof varName !== 'string') { + const varName = + typeof mapFn === 'function' + ? mapFn(value as string | null, path) + : (value as string); + + if ( + typeof varName !== 'string' || + varName !== cssesc(varName, { isIdentifier: true }) + ) { throw new Error( - `The map function used by "createGlobalThemeContract" must return a string and instead returned "${value}".`, + `Invalid variable name for "${path.join('.')}": ${varName}`, ); } - const cssVarName = cssesc( - varName.match(/^[0-9]/) ? `_${varName}` : varName, - { - isIdentifier: true, - }, - ); - return `var(--${cssVarName})` as const; + + return `var(--${varName})`; }); } diff --git a/packages/private/src/index.ts b/packages/private/src/index.ts index 51a4a856c..86a6fb1a9 100644 --- a/packages/private/src/index.ts +++ b/packages/private/src/index.ts @@ -2,4 +2,3 @@ export type { Contract, MapLeafNodes, CSSVarFunction } from './types'; export { getVarName } from './getVarName'; export { get } from './get'; export { walkObject } from './walkObject'; -export type { Primitive } from './walkObject'; diff --git a/packages/private/src/walkObject.ts b/packages/private/src/walkObject.ts index a1257b93b..09983953d 100644 --- a/packages/private/src/walkObject.ts +++ b/packages/private/src/walkObject.ts @@ -1,6 +1,6 @@ import { MapLeafNodes } from './types'; -export type Primitive = string | number | null | undefined; +type Primitive = string | number | null | undefined; type Walkable = { [Key in string | number]: Primitive | Walkable; From 06ecb1ae6b233545b36bbe2d501ffe6bd24d6a22 Mon Sep 17 00:00:00 2001 From: Mark Dalgleish Date: Fri, 27 Aug 2021 10:50:46 +1000 Subject: [PATCH 7/9] Tweak examples --- .changeset/shiny-bees-rest.md | 8 ++++---- README.md | 8 ++++---- site/docs/styling-api.md | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/.changeset/shiny-bees-rest.md b/.changeset/shiny-bees-rest.md index 3c4453744..ee30dfac5 100644 --- a/.changeset/shiny-bees-rest.md +++ b/.changeset/shiny-bees-rest.md @@ -17,10 +17,10 @@ import { export const vars = createGlobalThemeContract({ color: { - brand: 'ui-color-brand' + brand: 'color-brand' }, font: { - body: 'ui-font-body' + body: 'font-body' } }); @@ -54,7 +54,7 @@ export const vars = createGlobalThemeContract( body: 'font-body' } }, - (value) => `ui-${value}` + (value) => `prefix-${value}` ); ``` @@ -76,6 +76,6 @@ export const vars = createGlobalThemeContract( body: null } }, - (_value, path) => path.join('-') + (_value, path) => `prefix-${path.join('-')}` ); ``` \ No newline at end of file diff --git a/README.md b/README.md index 7250fefa3..68e14b6cc 100644 --- a/README.md +++ b/README.md @@ -639,10 +639,10 @@ import { export const vars = createGlobalThemeContract({ color: { - brand: 'ui-color-brand' + brand: 'color-brand' }, font: { - body: 'ui-font-body' + body: 'font-body' } }); @@ -675,7 +675,7 @@ export const vars = createGlobalThemeContract({ font: { body: 'font-body' } -}, (value) => `ui-${value}`); +}, (value) => `prefix-${value}`); ``` You can also use the map function to automatically generate names from the object path, joining keys with a hyphen. @@ -695,7 +695,7 @@ export const vars = createGlobalThemeContract({ font: { body: null } -}, (_value, path) => path.join('-')); +}, (_value, path) => `prefix-${path.join('-')}`); ``` ### assignVars diff --git a/site/docs/styling-api.md b/site/docs/styling-api.md index e70eec922..74c8f81b0 100644 --- a/site/docs/styling-api.md +++ b/site/docs/styling-api.md @@ -349,10 +349,10 @@ import { export const vars = createGlobalThemeContract({ color: { - brand: 'ui-color-brand' + brand: 'color-brand' }, font: { - body: 'ui-font-body' + body: 'font-body' } }); @@ -386,7 +386,7 @@ export const vars = createGlobalThemeContract( body: 'font-body' } }, - (value) => `ui-${value}` + (value) => `prefix-${value}` ); ``` @@ -408,7 +408,7 @@ export const vars = createGlobalThemeContract( body: null } }, - (_value, path) => path.join('-') + (_value, path) => `prefix-${path.join('-')}` ); ``` From 146d97f8fec52742aec7322163bd0fb7940ea513 Mon Sep 17 00:00:00 2001 From: Mark Dalgleish Date: Fri, 27 Aug 2021 10:51:31 +1000 Subject: [PATCH 8/9] Fix readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 68e14b6cc..dd973ffcb 100644 --- a/README.md +++ b/README.md @@ -1013,4 +1013,4 @@ const styles = { ## License -MIT. \ No newline at end of file +MIT. From f6c937d177b013ef7d2cee01547e3d6745182ebe Mon Sep 17 00:00:00 2001 From: Mark Dalgleish Date: Fri, 27 Aug 2021 14:06:03 +1000 Subject: [PATCH 9/9] Ignore leading double hyphens --- packages/css/src/vars.test.ts | 43 +++++++++++++++++++++++++++++++++++ packages/css/src/vars.ts | 5 +++- 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/packages/css/src/vars.test.ts b/packages/css/src/vars.test.ts index c9ee173b4..841be4838 100644 --- a/packages/css/src/vars.test.ts +++ b/packages/css/src/vars.test.ts @@ -89,6 +89,26 @@ describe('createGlobalThemeContract', () => { `); }); + it('ignores leading double hyphen', () => { + expect( + createGlobalThemeContract({ + color: { + red: '--color-red', + blue: '--color-blue', + green: '--color-green', + }, + }), + ).toMatchInlineSnapshot(` + Object { + "color": Object { + "blue": "var(--color-blue)", + "green": "var(--color-green)", + "red": "var(--color-red)", + }, + } + `); + }); + it('supports adding a prefix', () => { expect( createGlobalThemeContract( @@ -112,6 +132,29 @@ describe('createGlobalThemeContract', () => { `); }); + it('ignores leading double hyphen when adding a prefix', () => { + expect( + createGlobalThemeContract( + { + color: { + red: 'color-red', + blue: 'color-blue', + green: 'color-green', + }, + }, + (value) => `--prefix-${value}`, + ), + ).toMatchInlineSnapshot(` + Object { + "color": Object { + "blue": "var(--prefix-color-blue)", + "green": "var(--prefix-color-green)", + "red": "var(--prefix-color-red)", + }, + } + `); + }); + it('supports path based names', () => { expect( createGlobalThemeContract( diff --git a/packages/css/src/vars.ts b/packages/css/src/vars.ts index 2064f6ef8..40d682a33 100644 --- a/packages/css/src/vars.ts +++ b/packages/css/src/vars.ts @@ -89,11 +89,14 @@ export function createGlobalThemeContract( mapFn?: (value: string | null, path: Array) => string, ) { return walkObject(tokens, (value, path) => { - const varName = + const rawVarName = typeof mapFn === 'function' ? mapFn(value as string | null, path) : (value as string); + const varName = + typeof rawVarName === 'string' ? rawVarName.replace(/^\-\-/, '') : null; + if ( typeof varName !== 'string' || varName !== cssesc(varName, { isIdentifier: true })