From 5d6ccfde98e31ed12d33d7b1d45dd1a45e71a073 Mon Sep 17 00:00:00 2001 From: Aaron Casanova <32409546+aaronccasanova@users.noreply.github.com> Date: Fri, 29 Sep 2023 13:49:53 -0700 Subject: [PATCH 01/29] Deprecate JSON exports --- polaris-tokens/package.json | 1 - polaris-tokens/scripts/index.ts | 8 +------- polaris-tokens/scripts/toJSON.ts | 22 ---------------------- 3 files changed, 1 insertion(+), 30 deletions(-) delete mode 100644 polaris-tokens/scripts/toJSON.ts diff --git a/polaris-tokens/package.json b/polaris-tokens/package.json index 16041d2452b..4ce41d96042 100644 --- a/polaris-tokens/package.json +++ b/polaris-tokens/package.json @@ -14,7 +14,6 @@ "import": "./dist/esm/build/index.mjs", "require": "./dist/cjs/build/index.js" }, - "./json/*": "./dist/json/*", "./css/*": "./dist/css/*", "./scss/*": "./dist/scss/*" }, diff --git a/polaris-tokens/scripts/index.ts b/polaris-tokens/scripts/index.ts index 37502cb78e0..3865c88884d 100644 --- a/polaris-tokens/scripts/index.ts +++ b/polaris-tokens/scripts/index.ts @@ -1,13 +1,7 @@ -import {toJSON} from './toJSON'; import {toMediaConditions} from './toMediaConditions'; import {toStyleSheet} from './toStyleSheet'; import {toValues} from './toValues'; (async () => { - await Promise.all([ - toJSON(), - toMediaConditions(), - toStyleSheet(), - toValues(), - ]); + await Promise.all([toMediaConditions(), toStyleSheet(), toValues()]); })(); diff --git a/polaris-tokens/scripts/toJSON.ts b/polaris-tokens/scripts/toJSON.ts deleted file mode 100644 index 6299d273520..00000000000 --- a/polaris-tokens/scripts/toJSON.ts +++ /dev/null @@ -1,22 +0,0 @@ -import fs from 'fs'; -import path from 'path'; - -import {metaThemeDefault} from '../src/themes'; - -const outputDir = path.join(__dirname, '../dist/json'); - -export async function toJSON() { - await fs.promises.mkdir(outputDir, {recursive: true}).catch((error) => { - if (error.code !== 'EEXIST') { - throw error; - } - }); - - for (const [tokenGroupName, metaTokenGroup] of Object.entries( - metaThemeDefault, - )) { - const filePath = path.join(outputDir, `${tokenGroupName}.json`); - - await fs.promises.writeFile(filePath, JSON.stringify(metaTokenGroup)); - } -} From 6fd5b63e3e5dbc36d4112c6e9aefc0963b8ab7b1 Mon Sep 17 00:00:00 2001 From: Aaron Casanova <32409546+aaronccasanova@users.noreply.github.com> Date: Fri, 29 Sep 2023 13:53:54 -0700 Subject: [PATCH 02/29] Deprecate tokens export --- polaris-tokens/scripts/toValues.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/polaris-tokens/scripts/toValues.ts b/polaris-tokens/scripts/toValues.ts index 631563f207e..e7b4f53cfe2 100644 --- a/polaris-tokens/scripts/toValues.ts +++ b/polaris-tokens/scripts/toValues.ts @@ -25,7 +25,6 @@ export async function toValues() { [ `export * from '../src/index';`, Object.entries(themeDefault).map(createExport), - createExport(['tokens', themeDefault]), createExport([ 'themes', Object.fromEntries( From ae1ebe75ef3c041455e801e78913918b2123c8ee Mon Sep 17 00:00:00 2001 From: Aaron Casanova <32409546+aaronccasanova@users.noreply.github.com> Date: Fri, 29 Sep 2023 13:55:27 -0700 Subject: [PATCH 03/29] Deprecate token group exports --- polaris-tokens/scripts/toValues.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/polaris-tokens/scripts/toValues.ts b/polaris-tokens/scripts/toValues.ts index e7b4f53cfe2..7510400e9fc 100644 --- a/polaris-tokens/scripts/toValues.ts +++ b/polaris-tokens/scripts/toValues.ts @@ -24,7 +24,6 @@ export async function toValues() { path.join(outputDir, 'index.ts'), [ `export * from '../src/index';`, - Object.entries(themeDefault).map(createExport), createExport([ 'themes', Object.fromEntries( From b7b9f7c5a1065ca71fa48be82fc86b9d0b334f5b Mon Sep 17 00:00:00 2001 From: Aaron Casanova <32409546+aaronccasanova@users.noreply.github.com> Date: Fri, 29 Sep 2023 13:59:29 -0700 Subject: [PATCH 04/29] Remove unused metaThemeDefault import from toValues transform --- polaris-tokens/scripts/toValues.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/polaris-tokens/scripts/toValues.ts b/polaris-tokens/scripts/toValues.ts index 7510400e9fc..7748ada03f1 100644 --- a/polaris-tokens/scripts/toValues.ts +++ b/polaris-tokens/scripts/toValues.ts @@ -1,7 +1,7 @@ import fs from 'fs'; import path from 'path'; -import {metaThemes, metaThemeDefault} from '../src/themes'; +import {metaThemes} from '../src/themes'; import { extractMetaThemeValues, resolveMetaThemeRefs, @@ -16,10 +16,6 @@ export async function toValues() { } }); - const themeDefault = extractMetaThemeValues( - resolveMetaThemeRefs(metaThemeDefault), - ); - await fs.promises.writeFile( path.join(outputDir, 'index.ts'), [ From ebea495af9884dab2e9ce21c802350db54d7a640 Mon Sep 17 00:00:00 2001 From: Aaron Casanova <32409546+aaronccasanova@users.noreply.github.com> Date: Fri, 29 Sep 2023 14:03:58 -0700 Subject: [PATCH 05/29] Expose metaThemes from Polaris tokens --- polaris-tokens/src/index.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/polaris-tokens/src/index.ts b/polaris-tokens/src/index.ts index e47a1d0a17b..561e19bf8ee 100644 --- a/polaris-tokens/src/index.ts +++ b/polaris-tokens/src/index.ts @@ -8,6 +8,8 @@ export type { MetadataGroup, } from './types'; +export {metaThemes} from './themes'; + export type {ThemeName, Theme} from './themes/types'; export {themeNameDefault, themeNames} from './themes/constants'; From 4666c9e0fce5fa4e4086a8713ba5cf55685c3664 Mon Sep 17 00:00:00 2001 From: Aaron Casanova <32409546+aaronccasanova@users.noreply.github.com> Date: Fri, 29 Sep 2023 14:19:41 -0700 Subject: [PATCH 06/29] Deprecate metadata object and type exports --- polaris-tokens/src/index.ts | 1 - polaris-tokens/src/metadata.ts | 15 --------------- 2 files changed, 16 deletions(-) delete mode 100644 polaris-tokens/src/metadata.ts diff --git a/polaris-tokens/src/index.ts b/polaris-tokens/src/index.ts index 561e19bf8ee..b594274d34a 100644 --- a/polaris-tokens/src/index.ts +++ b/polaris-tokens/src/index.ts @@ -1,4 +1,3 @@ -export * from './metadata'; export * from './utilities'; export {breakpointsAliases} from './themes/base/breakpoints'; export type { diff --git a/polaris-tokens/src/metadata.ts b/polaris-tokens/src/metadata.ts deleted file mode 100644 index 94f52359b45..00000000000 --- a/polaris-tokens/src/metadata.ts +++ /dev/null @@ -1,15 +0,0 @@ -import {metaThemeDefault} from './themes'; -import type {Exact, MetadataBase} from './types'; -import {resolveMetaThemeRefs} from './themes/utils'; - -export const metadata = resolveMetaThemeRefs(metaThemeDefault); - -export type Metadata = typeof metadata; - -/** - * Identity function that simply returns the provided tokens with metadata, but additionally - * validates the input matches the `Metadata` type exactly and infers all members. - */ -export function createMetadata>(metadata: T) { - return metadata; -} From d84684db15cb737b2fe7dd871925bc9f8f208a25 Mon Sep 17 00:00:00 2001 From: Aaron Casanova <32409546+aaronccasanova@users.noreply.github.com> Date: Fri, 29 Sep 2023 14:21:48 -0700 Subject: [PATCH 07/29] Deprecate Tokens type export --- polaris-tokens/src/index.ts | 7 +------ polaris-tokens/src/types.ts | 6 ------ polaris-tokens/src/utilities.ts | 13 ++++++------- 3 files changed, 7 insertions(+), 19 deletions(-) diff --git a/polaris-tokens/src/index.ts b/polaris-tokens/src/index.ts index b594274d34a..0e3e80448fd 100644 --- a/polaris-tokens/src/index.ts +++ b/polaris-tokens/src/index.ts @@ -1,11 +1,6 @@ export * from './utilities'; export {breakpointsAliases} from './themes/base/breakpoints'; -export type { - TokenGroup, - Tokens, - MetadataProperties, - MetadataGroup, -} from './types'; +export type {TokenGroup, MetadataProperties, MetadataGroup} from './types'; export {metaThemes} from './themes'; diff --git a/polaris-tokens/src/types.ts b/polaris-tokens/src/types.ts index c8f2450e842..096a6b7dd1c 100644 --- a/polaris-tokens/src/types.ts +++ b/polaris-tokens/src/types.ts @@ -1,5 +1,3 @@ -import type {Metadata} from './metadata'; - export type Entry = [keyof T, T[keyof T]]; export type Entries = Entry[]; export type Experimental = `${T}-experimental`; @@ -21,10 +19,6 @@ export type TokenGroup = { [K in keyof T]: T[K]['value']; }; -export type Tokens = { - [TokenGroupName in keyof Metadata]: TokenGroup; -}; - // The following utility types are copied directly from `type-fest`: // https://github.com/sindresorhus/type-fest diff --git a/polaris-tokens/src/utilities.ts b/polaris-tokens/src/utilities.ts index 44082a84d6c..c728f11d185 100644 --- a/polaris-tokens/src/utilities.ts +++ b/polaris-tokens/src/utilities.ts @@ -1,9 +1,10 @@ -import type {Entry, Exact, MetadataGroup, Tokens, TokenGroup} from './types'; +import type {Entry, Exact, MetadataGroup, TokenGroup} from './types'; import type { breakpoints as metaBreakpointsTokenGroup, BreakpointsTokenGroup, BreakpointsTokenName, } from './themes/base/breakpoints'; +import type {Theme} from './themes/types'; const BASE_FONT_SIZE = 16; @@ -123,12 +124,10 @@ export function getKeyframeNames(motionTokenGroup: TokenGroup) { * * Result: ['--p-color-bg-app', '--p-color-text', etc...] */ -export function getCustomPropertyNames(tokens: Tokens) { - return Object.entries(tokens) - .map(([_, tokenGroup]: [string, TokenGroup]) => - Object.keys(tokenGroup).map((token) => createVar(token)), - ) - .flat(); +export function getCustomPropertyNames(theme: Theme) { + return Object.values(theme).flatMap((tokenGroup) => + Object.keys(tokenGroup).map((token) => createVar(token)), + ); } export function removeMetadata>( From ea108e5532b5edeba2b0fb586ecd798ef87feff1 Mon Sep 17 00:00:00 2001 From: Aaron Casanova <32409546+aaronccasanova@users.noreply.github.com> Date: Fri, 29 Sep 2023 14:34:03 -0700 Subject: [PATCH 08/29] Deprecate createExact, getKeyframeNames, getUnit, isKeyOf, rem, removeMetadata, toEm, and tokensToRems exports --- polaris-tokens/src/index.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/polaris-tokens/src/index.ts b/polaris-tokens/src/index.ts index 0e3e80448fd..e16cb01f5c6 100644 --- a/polaris-tokens/src/index.ts +++ b/polaris-tokens/src/index.ts @@ -1,7 +1,16 @@ -export * from './utilities'; export {breakpointsAliases} from './themes/base/breakpoints'; export type {TokenGroup, MetadataProperties, MetadataGroup} from './types'; +export { + createVar, + createVarName, + getCustomPropertyNames, + getMediaConditions, + toPx, + toPxs, + toRem, +} from './utilities'; + export {metaThemes} from './themes'; export type {ThemeName, Theme} from './themes/types'; From 1470aae07bed9c45b67466ef9a758802c5026f38 Mon Sep 17 00:00:00 2001 From: Aaron Casanova <32409546+aaronccasanova@users.noreply.github.com> Date: Fri, 29 Sep 2023 14:35:31 -0700 Subject: [PATCH 09/29] Rename src/utilities to src/utils --- polaris-tokens/scripts/toStyleSheet.ts | 2 +- polaris-tokens/src/index.ts | 2 +- polaris-tokens/src/themes/base/border.ts | 2 +- polaris-tokens/src/themes/base/font.ts | 2 +- polaris-tokens/src/themes/base/index.ts | 2 +- polaris-tokens/src/themes/base/space.ts | 2 +- polaris-tokens/src/themes/utils.ts | 2 +- polaris-tokens/src/{utilities.ts => utils.ts} | 0 polaris-tokens/tests/utilities.test.js | 2 +- 9 files changed, 8 insertions(+), 8 deletions(-) rename polaris-tokens/src/{utilities.ts => utils.ts} (100%) diff --git a/polaris-tokens/scripts/toStyleSheet.ts b/polaris-tokens/scripts/toStyleSheet.ts index 067756bef89..084f52642dc 100644 --- a/polaris-tokens/scripts/toStyleSheet.ts +++ b/polaris-tokens/scripts/toStyleSheet.ts @@ -5,7 +5,7 @@ import type {MetaThemeShape, MetaTokenGroupShape} from '../src/themes/types'; import {metaThemePartials, metaThemeDefault} from '../src/themes'; import {themeNameDefault} from '../src/themes/constants'; import {createThemeSelector} from '../src/themes/utils'; -import {createVar} from '../src/utilities'; +import {createVar} from '../src/utils'; import type {Entries} from '../src/types'; const cssOutputDir = path.join(__dirname, '../dist/css'); diff --git a/polaris-tokens/src/index.ts b/polaris-tokens/src/index.ts index e16cb01f5c6..557c1819ad2 100644 --- a/polaris-tokens/src/index.ts +++ b/polaris-tokens/src/index.ts @@ -9,7 +9,7 @@ export { toPx, toPxs, toRem, -} from './utilities'; +} from './utils'; export {metaThemes} from './themes'; diff --git a/polaris-tokens/src/themes/base/border.ts b/polaris-tokens/src/themes/base/border.ts index bb0a4ff8b21..c4693f3f767 100644 --- a/polaris-tokens/src/themes/base/border.ts +++ b/polaris-tokens/src/themes/base/border.ts @@ -1,7 +1,7 @@ import type {Experimental} from '../../types'; import type {MetaTokenProperties} from '../types'; import {size} from '../../size'; -import {createVar as createVarName} from '../../utilities'; +import {createVar as createVarName} from '../../utils'; type BorderRadiusScaleExperimental = Experimental<'0' | '1_5'>; diff --git a/polaris-tokens/src/themes/base/font.ts b/polaris-tokens/src/themes/base/font.ts index 221fb6b916e..0f62054f0f3 100644 --- a/polaris-tokens/src/themes/base/font.ts +++ b/polaris-tokens/src/themes/base/font.ts @@ -1,7 +1,7 @@ import {size} from '../../size'; import type {Experimental} from '../../types'; import type {MetaTokenProperties} from '../types'; -import {createVar as createVarName} from '../../utilities'; +import {createVar as createVarName} from '../../utils'; export type FontFamilyPrefix = 'font-family'; type FontFamilyAlias = 'sans' | 'mono'; diff --git a/polaris-tokens/src/themes/base/index.ts b/polaris-tokens/src/themes/base/index.ts index cc913acbec9..c6b73a646a5 100644 --- a/polaris-tokens/src/themes/base/index.ts +++ b/polaris-tokens/src/themes/base/index.ts @@ -1,4 +1,4 @@ -import {createExact, tokensToRems} from '../../utilities'; +import {createExact, tokensToRems} from '../../utils'; import type {MetaThemeShape} from '../types'; import {border} from './border'; diff --git a/polaris-tokens/src/themes/base/space.ts b/polaris-tokens/src/themes/base/space.ts index 58ac2455bb9..8a8e7ecd4b7 100644 --- a/polaris-tokens/src/themes/base/space.ts +++ b/polaris-tokens/src/themes/base/space.ts @@ -1,6 +1,6 @@ import {size} from '../../size'; import type {Experimental} from '../../types'; -import {createVarName} from '../../utilities'; +import {createVarName} from '../../utils'; import type {MetaTokenProperties} from '../types'; type SpaceScaleExperimental = Experimental<'1_5'>; diff --git a/polaris-tokens/src/themes/utils.ts b/polaris-tokens/src/themes/utils.ts index df5b72de184..565ce888ff6 100644 --- a/polaris-tokens/src/themes/utils.ts +++ b/polaris-tokens/src/themes/utils.ts @@ -1,7 +1,7 @@ import deepmerge from 'deepmerge'; import type {Entry, Exact} from '../types'; -import {createExact} from '../utilities'; +import {createExact} from '../utils'; import type { ExtractMetaThemeValues, diff --git a/polaris-tokens/src/utilities.ts b/polaris-tokens/src/utils.ts similarity index 100% rename from polaris-tokens/src/utilities.ts rename to polaris-tokens/src/utils.ts diff --git a/polaris-tokens/tests/utilities.test.js b/polaris-tokens/tests/utilities.test.js index 7f7b4909cb3..eae68d63968 100644 --- a/polaris-tokens/tests/utilities.test.js +++ b/polaris-tokens/tests/utilities.test.js @@ -8,7 +8,7 @@ import { toRem, getUnit, getMediaConditions, -} from '../src/utilities'; +} from '../src/utils'; import {resolveMetaThemeRefs} from '../src/themes/utils'; const mockTokenGroup = { From 94a13e81d77ea567484c9ed3596cfe942e6d929a Mon Sep 17 00:00:00 2001 From: Aaron Casanova <32409546+aaronccasanova@users.noreply.github.com> Date: Fri, 29 Sep 2023 14:47:38 -0700 Subject: [PATCH 10/29] Rename getCustomPropertyNames to getThemeVarNames --- polaris-tokens/src/index.ts | 2 +- polaris-tokens/src/utils.ts | 2 +- polaris-tokens/tests/utilities.test.js | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/polaris-tokens/src/index.ts b/polaris-tokens/src/index.ts index 557c1819ad2..4953acaa053 100644 --- a/polaris-tokens/src/index.ts +++ b/polaris-tokens/src/index.ts @@ -4,7 +4,7 @@ export type {TokenGroup, MetadataProperties, MetadataGroup} from './types'; export { createVar, createVarName, - getCustomPropertyNames, + getThemeVarNames, getMediaConditions, toPx, toPxs, diff --git a/polaris-tokens/src/utils.ts b/polaris-tokens/src/utils.ts index c728f11d185..3e84117f7bd 100644 --- a/polaris-tokens/src/utils.ts +++ b/polaris-tokens/src/utils.ts @@ -124,7 +124,7 @@ export function getKeyframeNames(motionTokenGroup: TokenGroup) { * * Result: ['--p-color-bg-app', '--p-color-text', etc...] */ -export function getCustomPropertyNames(theme: Theme) { +export function getThemeVarNames(theme: Theme) { return Object.values(theme).flatMap((tokenGroup) => Object.keys(tokenGroup).map((token) => createVar(token)), ); diff --git a/polaris-tokens/tests/utilities.test.js b/polaris-tokens/tests/utilities.test.js index eae68d63968..1858ea790e1 100644 --- a/polaris-tokens/tests/utilities.test.js +++ b/polaris-tokens/tests/utilities.test.js @@ -1,6 +1,6 @@ import { createVar, - getCustomPropertyNames, + getThemeVarNames, getKeyframeNames, tokensToRems, toPx, @@ -50,9 +50,9 @@ describe('createVar', () => { }); }); -describe('getCustomPropertyNames', () => { +describe('getThemeVarNames', () => { it('extracts the token names', () => { - expect(getCustomPropertyNames(mockTokens)).toStrictEqual([ + expect(getThemeVarNames(mockTokens)).toStrictEqual([ '--p-design-token-1', '--p-design-token-2', ]); From 9cc72868d9356a35cb9fb75688f6208978a13aad Mon Sep 17 00:00:00 2001 From: Aaron Casanova <32409546+aaronccasanova@users.noreply.github.com> Date: Fri, 29 Sep 2023 15:00:53 -0700 Subject: [PATCH 11/29] Updated createVar behavior and improved TypeScript validation --- polaris-tokens/scripts/toStyleSheet.ts | 12 ++++++++---- polaris-tokens/src/themes/base/border.ts | 5 ----- polaris-tokens/src/themes/base/font.ts | 5 ----- polaris-tokens/src/themes/base/text.ts | 2 +- polaris-tokens/src/themes/types.ts | 6 ++++++ polaris-tokens/src/utils.ts | 14 ++++++++------ polaris-tokens/tests/utilities.test.js | 12 +++++++++++- 7 files changed, 34 insertions(+), 22 deletions(-) diff --git a/polaris-tokens/scripts/toStyleSheet.ts b/polaris-tokens/scripts/toStyleSheet.ts index 084f52642dc..0e14fd2e68e 100644 --- a/polaris-tokens/scripts/toStyleSheet.ts +++ b/polaris-tokens/scripts/toStyleSheet.ts @@ -1,11 +1,15 @@ import fs from 'fs'; import path from 'path'; -import type {MetaThemeShape, MetaTokenGroupShape} from '../src/themes/types'; +import type { + MetaThemeShape, + MetaTokenGroupShape, + TokenName, +} from '../src/themes/types'; import {metaThemePartials, metaThemeDefault} from '../src/themes'; import {themeNameDefault} from '../src/themes/constants'; import {createThemeSelector} from '../src/themes/utils'; -import {createVar} from '../src/utils'; +import {createVarName} from '../src/utils'; import type {Entries} from '../src/types'; const cssOutputDir = path.join(__dirname, '../dist/css'); @@ -25,8 +29,8 @@ export function getMetaTokenGroupDecls(metaTokenGroup: MetaTokenGroupShape) { return Object.entries(metaTokenGroup) .map(([tokenName, {value}]) => tokenName.startsWith('motion-keyframes') - ? `${createVar(tokenName)}:p-${tokenName};` - : `${createVar(tokenName)}:${value};`, + ? `${createVarName(tokenName as TokenName)}:p-${tokenName};` + : `${createVarName(tokenName as TokenName)}:${value};`, ) .join(''); } diff --git a/polaris-tokens/src/themes/base/border.ts b/polaris-tokens/src/themes/base/border.ts index c4693f3f767..11813bc57e7 100644 --- a/polaris-tokens/src/themes/base/border.ts +++ b/polaris-tokens/src/themes/base/border.ts @@ -1,7 +1,6 @@ import type {Experimental} from '../../types'; import type {MetaTokenProperties} from '../types'; import {size} from '../../size'; -import {createVar as createVarName} from '../../utils'; type BorderRadiusScaleExperimental = Experimental<'0' | '1_5'>; @@ -144,7 +143,3 @@ export const border: { value: '1px', }, }; - -export function createVar(borderTokenName: BorderTokenName) { - return `var(${createVarName(borderTokenName)})`; -} diff --git a/polaris-tokens/src/themes/base/font.ts b/polaris-tokens/src/themes/base/font.ts index 0f62054f0f3..87c0fad285b 100644 --- a/polaris-tokens/src/themes/base/font.ts +++ b/polaris-tokens/src/themes/base/font.ts @@ -1,7 +1,6 @@ import {size} from '../../size'; import type {Experimental} from '../../types'; import type {MetaTokenProperties} from '../types'; -import {createVar as createVarName} from '../../utils'; export type FontFamilyPrefix = 'font-family'; type FontFamilyAlias = 'sans' | 'mono'; @@ -203,7 +202,3 @@ export const font: { value: '48px', }, }; - -export function createVar(fontTokenName: FontTokenName) { - return `var(${createVarName(fontTokenName)})`; -} diff --git a/polaris-tokens/src/themes/base/text.ts b/polaris-tokens/src/themes/base/text.ts index 0f1c6cea8a0..a927b7501d3 100644 --- a/polaris-tokens/src/themes/base/text.ts +++ b/polaris-tokens/src/themes/base/text.ts @@ -1,7 +1,7 @@ import type {MetaTokenProperties} from '../types'; +import {createVar} from '../../utils'; import type {FontPrefix} from './font'; -import {createVar} from './font'; export type TextVariant = | 'heading-3xl' diff --git a/polaris-tokens/src/themes/types.ts b/polaris-tokens/src/themes/types.ts index 38e00fb636c..1a96ca1b823 100644 --- a/polaris-tokens/src/themes/types.ts +++ b/polaris-tokens/src/themes/types.ts @@ -8,6 +8,12 @@ export type ThemeName = typeof themeNames[number]; export type ThemeBase = ExtractMetaThemeValues; export type Theme = ExtractMetaThemeValues; +export type TokenName = { + [TokenGroupName in keyof Theme]: { + [TokenName in keyof Theme[TokenGroupName]]: TokenName; + }[keyof Theme[TokenGroupName]]; +}[keyof Theme]; + export interface MetaTokenProperties { value: string; description?: string; diff --git a/polaris-tokens/src/utils.ts b/polaris-tokens/src/utils.ts index 3e84117f7bd..25ee9ce47fe 100644 --- a/polaris-tokens/src/utils.ts +++ b/polaris-tokens/src/utils.ts @@ -4,7 +4,7 @@ import type { BreakpointsTokenGroup, BreakpointsTokenName, } from './themes/base/breakpoints'; -import type {Theme} from './themes/types'; +import type {Theme, TokenName} from './themes/types'; const BASE_FONT_SIZE = 16; @@ -100,12 +100,12 @@ export function tokensToRems>(tokenGroup: T) { ) as T; } -export function createVarName(token: string) { - return `--p-${token}`; +export function createVarName(tokenName: TokenName) { + return `--p-${tokenName}`; } -export function createVar(token: string) { - return `--p-${token}`; +export function createVar(tokenName: TokenName) { + return `var(${createVarName(tokenName)})`; } /** @@ -126,7 +126,9 @@ export function getKeyframeNames(motionTokenGroup: TokenGroup) { */ export function getThemeVarNames(theme: Theme) { return Object.values(theme).flatMap((tokenGroup) => - Object.keys(tokenGroup).map((token) => createVar(token)), + Object.keys(tokenGroup).map((tokenName) => + createVarName(tokenName as TokenName), + ), ); } diff --git a/polaris-tokens/tests/utilities.test.js b/polaris-tokens/tests/utilities.test.js index 1858ea790e1..cf0e416dc5b 100644 --- a/polaris-tokens/tests/utilities.test.js +++ b/polaris-tokens/tests/utilities.test.js @@ -1,5 +1,6 @@ import { createVar, + createVarName, getThemeVarNames, getKeyframeNames, tokensToRems, @@ -42,10 +43,19 @@ const mockTokens = { }; describe('createVar', () => { - it('converts the token into a polaris css variable name', () => { + it('converts the token into a polaris css variable', () => { const token = 'foo'; const result = createVar(token); + expect(result).toBe(`var(--p-${token})`); + }); +}); + +describe('createVarName', () => { + it('converts the token into a polaris css variable name', () => { + const token = 'foo'; + const result = createVarName(token); + expect(result).toBe(`--p-${token}`); }); }); From 659ed2e302148337152749cc6e5635d605cea55b Mon Sep 17 00:00:00 2001 From: Sophie Schneider Date: Mon, 2 Oct 2023 18:54:14 +0000 Subject: [PATCH 12/29] Add deprecated token utility docs --- .../migrating-from-v11-to-v12.md | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/polaris.shopify.com/content/version-guides/migrating-from-v11-to-v12.md b/polaris.shopify.com/content/version-guides/migrating-from-v11-to-v12.md index bb1964c6cf1..4d8bff8c415 100644 --- a/polaris.shopify.com/content/version-guides/migrating-from-v11-to-v12.md +++ b/polaris.shopify.com/content/version-guides/migrating-from-v11-to-v12.md @@ -840,6 +840,30 @@ git commit -m "Manually migrate X custom properties from Polaris v11 to v12" npx stylelint ``` +### Token utility updates + +#### Renames + +- `getCustomPropertyNames` renamed to `getThemeVarNames` + +#### Type deprecations + +- `Tokens` type is now deprecated, use the `Theme` type instead + +#### Utility deprecations + +If you are using these utilities, feel free to copy them from v11 into your own codebase. + +- `createExact` +- `getKeyframeNames` +- `getUnit` +- `isKeyOf` +- `rem` +- `removeMetadata` +- `toEm` +- `tokensToRems` +- `toJSON` + ## Manual updates and fixes ### A new web font From c6bb60c4953ad3e1a8a00055aae12d814e627db0 Mon Sep 17 00:00:00 2001 From: Aaron Casanova <32409546+aaronccasanova@users.noreply.github.com> Date: Mon, 2 Oct 2023 14:27:17 -0700 Subject: [PATCH 13/29] Initial isTokenName type guard --- polaris-tokens/scripts/toStyleSheet.ts | 22 +++++++++++----------- polaris-tokens/scripts/toValues.ts | 3 +++ polaris-tokens/src/themes/utils.ts | 19 +++++++++++++++++++ polaris-tokens/src/utils.ts | 2 +- 4 files changed, 34 insertions(+), 12 deletions(-) diff --git a/polaris-tokens/scripts/toStyleSheet.ts b/polaris-tokens/scripts/toStyleSheet.ts index 0e14fd2e68e..05db17377ce 100644 --- a/polaris-tokens/scripts/toStyleSheet.ts +++ b/polaris-tokens/scripts/toStyleSheet.ts @@ -1,14 +1,10 @@ import fs from 'fs'; import path from 'path'; -import type { - MetaThemeShape, - MetaTokenGroupShape, - TokenName, -} from '../src/themes/types'; +import type {MetaThemeShape, MetaTokenGroupShape} from '../src/themes/types'; import {metaThemePartials, metaThemeDefault} from '../src/themes'; import {themeNameDefault} from '../src/themes/constants'; -import {createThemeSelector} from '../src/themes/utils'; +import {createThemeSelector, isTokenName} from '../src/themes/utils'; import {createVarName} from '../src/utils'; import type {Entries} from '../src/types'; @@ -27,11 +23,15 @@ export function getMetaThemeDecls(metaTheme: MetaThemeShape) { /** Creates CSS declarations from a token group. */ export function getMetaTokenGroupDecls(metaTokenGroup: MetaTokenGroupShape) { return Object.entries(metaTokenGroup) - .map(([tokenName, {value}]) => - tokenName.startsWith('motion-keyframes') - ? `${createVarName(tokenName as TokenName)}:p-${tokenName};` - : `${createVarName(tokenName as TokenName)}:${value};`, - ) + .map(([tokenName, {value}]) => { + if (!isTokenName(tokenName)) { + throw new Error(`Invalid token name: ${tokenName}`); + } + + return tokenName.startsWith('motion-keyframes') + ? `${createVarName(tokenName)}:p-${tokenName};` + : `${createVarName(tokenName)}:${value};`; + }) .join(''); } diff --git a/polaris-tokens/scripts/toValues.ts b/polaris-tokens/scripts/toValues.ts index 7748ada03f1..3c573e96694 100644 --- a/polaris-tokens/scripts/toValues.ts +++ b/polaris-tokens/scripts/toValues.ts @@ -19,6 +19,8 @@ export async function toValues() { await fs.promises.writeFile( path.join(outputDir, 'index.ts'), [ + `import {themeNameDefault} from '../src/index';`, + `import {createIsTokenName} from '../src/themes/utils';`, `export * from '../src/index';`, createExport([ 'themes', @@ -29,6 +31,7 @@ export async function toValues() { ]), ), ]), + `export const isTokenName = createIsTokenName(themes[themeNameDefault]);`, ] .flat() .join('\n'), diff --git a/polaris-tokens/src/themes/utils.ts b/polaris-tokens/src/themes/utils.ts index 565ce888ff6..b5a7512356c 100644 --- a/polaris-tokens/src/themes/utils.ts +++ b/polaris-tokens/src/themes/utils.ts @@ -11,6 +11,8 @@ import type { MetaThemePartialShape, MetaTokenGroupShape, ThemeName, + TokenName, + Theme, } from './types'; import {metaThemeBase} from './base'; @@ -89,3 +91,20 @@ export function resolveMetaThemeRefs( ]), ) as T; } + +export function createIsTokenName(theme: Theme | MetaTheme) { + const tokenNames = new Set( + Object.values(theme).flatMap((tokenGroup) => + Object.keys(tokenGroup), + ) as TokenName[], + ); + + return (tokenName: unknown): tokenName is TokenName => + tokenNames.has(tokenName as TokenName); +} + +/** + * Important: Do not export from Polaris tokens. This utility is exposed + * in the `toValues` build step to ensure the `metaTheme` isn't in client bundles. + */ +export const isTokenName = createIsTokenName(metaThemeBase); diff --git a/polaris-tokens/src/utils.ts b/polaris-tokens/src/utils.ts index 3dba3f460d1..0e842eaa6b8 100644 --- a/polaris-tokens/src/utils.ts +++ b/polaris-tokens/src/utils.ts @@ -127,7 +127,7 @@ export function getKeyframeNames(motionTokenGroup: TokenGroup) { export function getThemeVarNames(theme: Theme) { return Object.values(theme).flatMap((tokenGroup) => Object.keys(tokenGroup).map((tokenName) => - createVarName(tokenName as TokenName), + createVarName(tokenName as keyof typeof tokenGroup), ), ); } From 241e92f5a14fda5fde33c82ba9ff4dbb6932e4ce Mon Sep 17 00:00:00 2001 From: Aaron Casanova <32409546+aaronccasanova@users.noreply.github.com> Date: Mon, 2 Oct 2023 14:34:23 -0700 Subject: [PATCH 14/29] Update isTokenName type guard --- polaris-tokens/src/themes/utils.ts | 8 ++------ polaris-tokens/src/utils.ts | 14 ++++++++------ 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/polaris-tokens/src/themes/utils.ts b/polaris-tokens/src/themes/utils.ts index b5a7512356c..ca0fd5ddf79 100644 --- a/polaris-tokens/src/themes/utils.ts +++ b/polaris-tokens/src/themes/utils.ts @@ -1,7 +1,7 @@ import deepmerge from 'deepmerge'; import type {Entry, Exact} from '../types'; -import {createExact} from '../utils'; +import {createExact, getTokenNames} from '../utils'; import type { ExtractMetaThemeValues, @@ -93,11 +93,7 @@ export function resolveMetaThemeRefs( } export function createIsTokenName(theme: Theme | MetaTheme) { - const tokenNames = new Set( - Object.values(theme).flatMap((tokenGroup) => - Object.keys(tokenGroup), - ) as TokenName[], - ); + const tokenNames = new Set(getTokenNames(theme)); return (tokenName: unknown): tokenName is TokenName => tokenNames.has(tokenName as TokenName); diff --git a/polaris-tokens/src/utils.ts b/polaris-tokens/src/utils.ts index 0e842eaa6b8..b34099eab97 100644 --- a/polaris-tokens/src/utils.ts +++ b/polaris-tokens/src/utils.ts @@ -4,7 +4,7 @@ import type { BreakpointsTokenGroup, BreakpointsTokenName, } from './themes/base/breakpoints'; -import type {Theme, TokenName} from './themes/types'; +import type {MetaTheme, Theme, TokenName} from './themes/types'; const BASE_FONT_SIZE = 16; @@ -119,17 +119,19 @@ export function getKeyframeNames(motionTokenGroup: TokenGroup) { .filter(Boolean); } +export function getTokenNames(theme: Theme | MetaTheme): TokenName[] { + return Object.values(theme).flatMap((tokenGroup) => + Object.keys(tokenGroup), + ) as TokenName[]; +} + /** * Allowed Polaris token custom properties. * * Result: ['--p-color-bg', '--p-color-text', etc...] */ export function getThemeVarNames(theme: Theme) { - return Object.values(theme).flatMap((tokenGroup) => - Object.keys(tokenGroup).map((tokenName) => - createVarName(tokenName as keyof typeof tokenGroup), - ), - ); + return getTokenNames(theme).map(createVarName); } export function removeMetadata>( From 43b992b048195b6774b0b319075a9fda89401c92 Mon Sep 17 00:00:00 2001 From: Aaron Casanova <32409546+aaronccasanova@users.noreply.github.com> Date: Mon, 2 Oct 2023 15:27:05 -0700 Subject: [PATCH 15/29] Updated theme creators to apply token to rem conversions --- polaris-tokens/src/themes/base/index.ts | 19 +++----- polaris-tokens/src/themes/utils.ts | 32 +++++++++++- polaris-tokens/src/utils.ts | 65 +++++++++++++++++-------- 3 files changed, 83 insertions(+), 33 deletions(-) diff --git a/polaris-tokens/src/themes/base/index.ts b/polaris-tokens/src/themes/base/index.ts index c6b73a646a5..c96ed9a94eb 100644 --- a/polaris-tokens/src/themes/base/index.ts +++ b/polaris-tokens/src/themes/base/index.ts @@ -1,5 +1,4 @@ -import {createExact, tokensToRems} from '../../utils'; -import type {MetaThemeShape} from '../types'; +import {createMetaThemeBase} from '../../utils'; import {border} from './border'; import {breakpoints} from './breakpoints'; @@ -13,18 +12,16 @@ import {text} from './text'; import {width} from './width'; import {zIndex} from './zIndex'; -const createMetaThemeBase = createExact(); - export const metaThemeBase = createMetaThemeBase({ - border: tokensToRems(border), - breakpoints: tokensToRems(breakpoints), + border, + breakpoints, color, - font: tokensToRems(font), - height: tokensToRems(height), + font, + height, motion, - shadow: tokensToRems(shadow), - space: tokensToRems(space), + shadow, + space, text, - width: tokensToRems(width), + width, zIndex, }); diff --git a/polaris-tokens/src/themes/utils.ts b/polaris-tokens/src/themes/utils.ts index ca0fd5ddf79..2ad2111c393 100644 --- a/polaris-tokens/src/themes/utils.ts +++ b/polaris-tokens/src/themes/utils.ts @@ -1,7 +1,7 @@ import deepmerge from 'deepmerge'; import type {Entry, Exact} from '../types'; -import {createExact, getTokenNames} from '../utils'; +import {getTokenNames, tokenGroupToRems, tokenGroupNamesToRems} from '../utils'; import type { ExtractMetaThemeValues, @@ -16,7 +16,35 @@ import type { } from './types'; import {metaThemeBase} from './base'; -export const createMetaThemePartial = createExact(); +/** + * Mimics the behavior of an identity function: + * - Validates the input matches the `MetaThemeShape` type exactly + * - Converts all `px` values to `rem` + * - Infers all members + * + * @example + * ``` + * const example = createMetaThemePartial({ + * color: { + * bg: {value: '#fff'}, + * }, + * }) + * ``` + * + * Where `typeof example` is inferred as `{ color: { bg: { value: string } } }` + */ +export function createMetaThemePartial< + T extends Exact, +>(metaThemePartial: T) { + return Object.fromEntries( + Object.entries(metaThemePartial).map(([tokenGroupName, tokenGroup]) => [ + tokenGroupName, + tokenGroup && tokenGroupNamesToRems.includes(tokenGroupName) + ? tokenGroupToRems(tokenGroup) + : tokenGroup, + ]), + ) as T; +} export function createMetaTheme>( metaThemePartial: T, diff --git a/polaris-tokens/src/utils.ts b/polaris-tokens/src/utils.ts index b34099eab97..a874c12a1fe 100644 --- a/polaris-tokens/src/utils.ts +++ b/polaris-tokens/src/utils.ts @@ -4,7 +4,13 @@ import type { BreakpointsTokenGroup, BreakpointsTokenName, } from './themes/base/breakpoints'; -import type {MetaTheme, Theme, TokenName} from './themes/types'; +import type { + MetaTheme, + MetaThemeShape, + MetaTokenGroupShape, + Theme, + TokenName, +} from './themes/types'; const BASE_FONT_SIZE = 16; @@ -88,13 +94,15 @@ export function rem(value: string) { ); } -export function tokensToRems>(tokenGroup: T) { +export function tokenGroupToRems( + metaTokenGroup: T, +) { return Object.fromEntries( - Object.entries(tokenGroup).map(([token, properties]) => [ - token, - {...properties, value: rem(properties.value)}, + Object.entries(metaTokenGroup).map(([tokenName, tokenProperties]) => [ + tokenName, + {...tokenProperties, value: rem(tokenProperties.value)}, ]), - // We loose the `tokenGroup` inference after transforming the object with + // We loose the `metaTokenGroup` inference after transforming the object with // `Object.fromEntries()` and `Object.entries()`. Thus, we cast the result // back to `T` since we are simply converting the `value` from px to rem. ) as T; @@ -227,26 +235,43 @@ export function isKeyOf( return Object.keys(obj).includes(key as string); } +export const tokenGroupNamesToRems = [ + 'border', + 'breakpoints', + 'font', + 'height', + 'shadow', + 'space', + 'text', + 'width', +]; + /** - * Identity function creator that returns the provided input, - * but additionally validates the input matches the type exactly - * and infers all members. - * - * TODO: Replace all instances with `satisfies` when we upgrade - * to TypeScript >=4.9 + * Mimics the behavior of an identity function: + * - Validates the input matches the `MetaThemeShape` type exactly + * - Converts all `px` values to `rem` + * - Infers all members * * @example * ``` - * type ExampleShape = { [key: string]: string } - * const createExample = createExact() - * - * const example = createExample({ - * foo: 'bar', + * const example = createMetaThemeBase({ + * color: { + * bg: {value: '#fff'}, + * }, * }) * ``` * - * Where `typeof example` is inferred as `{ foo: string }` + * Where `typeof example` is inferred as `{ color: { bg: { value: string } } }` */ -export function createExact() { - return >(obj: U) => obj; +export function createMetaThemeBase>( + metaTheme: T, +): T { + return Object.fromEntries( + Object.entries(metaTheme).map(([tokenGroupName, tokenGroup]) => [ + tokenGroupName, + tokenGroupNamesToRems.includes(tokenGroupName) + ? tokenGroupToRems(tokenGroup) + : tokenGroup, + ]), + ) as T; } From 2443fb6c343e45bb31539f4dc8825c9bf1af73d4 Mon Sep 17 00:00:00 2001 From: Aaron Casanova <32409546+aaronccasanova@users.noreply.github.com> Date: Mon, 2 Oct 2023 15:41:40 -0700 Subject: [PATCH 16/29] Deprecate legacy types and utils --- polaris-tokens/src/index.ts | 9 +++++++-- polaris-tokens/src/types.ts | 17 ----------------- polaris-tokens/src/utils.ts | 16 ++-------------- polaris-tokens/tests/utilities.test.js | 1 - 4 files changed, 9 insertions(+), 34 deletions(-) diff --git a/polaris-tokens/src/index.ts b/polaris-tokens/src/index.ts index 9ea59245453..19fc0358fd5 100644 --- a/polaris-tokens/src/index.ts +++ b/polaris-tokens/src/index.ts @@ -1,5 +1,4 @@ export {breakpointsAliases} from './themes/base/breakpoints'; -export type {TokenGroup, MetadataProperties, MetadataGroup} from './types'; export { createVar, @@ -13,7 +12,13 @@ export { export {metaThemes} from './themes'; -export type {ThemeName, Theme} from './themes/types'; +export type { + MetaThemeShape, + MetaTokenGroupShape, + MetaTokenProperties, + Theme, + ThemeName, +} from './themes/types'; export {themeNameDefault, themeNames} from './themes/constants'; diff --git a/polaris-tokens/src/types.ts b/polaris-tokens/src/types.ts index 096a6b7dd1c..8dc1892b978 100644 --- a/polaris-tokens/src/types.ts +++ b/polaris-tokens/src/types.ts @@ -2,23 +2,6 @@ export type Entry = [keyof T, T[keyof T]]; export type Entries = Entry[]; export type Experimental = `${T}-experimental`; -export interface MetadataProperties { - description?: string; - value: string; -} - -export interface MetadataGroup { - [token: string]: MetadataProperties; -} - -export interface MetadataBase { - [tokenGroup: string]: MetadataGroup; -} - -export type TokenGroup = { - [K in keyof T]: T[K]['value']; -}; - // The following utility types are copied directly from `type-fest`: // https://github.com/sindresorhus/type-fest diff --git a/polaris-tokens/src/utils.ts b/polaris-tokens/src/utils.ts index a874c12a1fe..0939459fe6d 100644 --- a/polaris-tokens/src/utils.ts +++ b/polaris-tokens/src/utils.ts @@ -1,4 +1,4 @@ -import type {Entry, Exact, MetadataGroup, TokenGroup} from './types'; +import type {Entry, Exact} from './types'; import type { breakpoints as metaBreakpointsTokenGroup, BreakpointsTokenGroup, @@ -121,7 +121,7 @@ export function createVar(tokenName: TokenName) { * * Result: ['p-keyframes-fade-in', 'p-keyframes-spin', etc...] */ -export function getKeyframeNames(motionTokenGroup: TokenGroup) { +export function getKeyframeNames(motionTokenGroup: MetaTokenGroupShape) { return Object.keys(motionTokenGroup) .map((token) => (token.startsWith('keyframes') ? `p-${token}` : null)) .filter(Boolean); @@ -142,18 +142,6 @@ export function getThemeVarNames(theme: Theme) { return getTokenNames(theme).map(createVarName); } -export function removeMetadata>( - tokenGroup: T, -) { - return Object.fromEntries( - Object.entries(tokenGroup).map((entry): Entry => { - const [tokenName, {value}] = entry as Entry; - - return [tokenName, value]; - }), - ) as TokenGroup; -} - export type MetaBreakpointsTokenGroup = typeof metaBreakpointsTokenGroup; /** diff --git a/polaris-tokens/tests/utilities.test.js b/polaris-tokens/tests/utilities.test.js index cf0e416dc5b..dc8d6fdcaee 100644 --- a/polaris-tokens/tests/utilities.test.js +++ b/polaris-tokens/tests/utilities.test.js @@ -162,7 +162,6 @@ describe('toRem', () => { describe('getMediaConditions', () => { it('transforms breakpoints tokens into directional media conditions', () => { - /** @type {TokenGroup} */ const breakpoints = { breakpoint1: '16px', breakpoint2: '32px', From c8707a4ff8a90130a3a6e7883906edc3399f379e Mon Sep 17 00:00:00 2001 From: Aaron Casanova <32409546+aaronccasanova@users.noreply.github.com> Date: Mon, 2 Oct 2023 15:54:29 -0700 Subject: [PATCH 17/29] Expose metaThemeDefault and MetaTheme --- polaris-tokens/src/index.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/polaris-tokens/src/index.ts b/polaris-tokens/src/index.ts index 19fc0358fd5..cc68814afd4 100644 --- a/polaris-tokens/src/index.ts +++ b/polaris-tokens/src/index.ts @@ -10,9 +10,10 @@ export { toRem, } from './utils'; -export {metaThemes} from './themes'; +export {metaThemes, metaThemeDefault} from './themes'; export type { + MetaTheme, MetaThemeShape, MetaTokenGroupShape, MetaTokenProperties, From 89a9fddf1ee18949e047c102e30243bc3d984850 Mon Sep 17 00:00:00 2001 From: Aaron Casanova <32409546+aaronccasanova@users.noreply.github.com> Date: Mon, 2 Oct 2023 15:54:46 -0700 Subject: [PATCH 18/29] Upgrade Polaris for VS Code --- polaris-for-vscode/src/server.ts | 44 ++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/polaris-for-vscode/src/server.ts b/polaris-for-vscode/src/server.ts index b2f0707aa1a..eeb47936342 100644 --- a/polaris-for-vscode/src/server.ts +++ b/polaris-for-vscode/src/server.ts @@ -1,5 +1,9 @@ -import {createVar, metadata} from '@shopify/polaris-tokens'; -import type {MetadataGroup} from '@shopify/polaris-tokens'; +import type {MetaTheme, MetaTokenGroupShape} from '@shopify/polaris-tokens'; +import { + createVarName, + metaThemeDefault, + isTokenName, +} from '@shopify/polaris-tokens'; import { createConnection, TextDocuments, @@ -19,16 +23,16 @@ const excludedTokenGroupNames = [] as const; type ExcludedTokenGroupName = typeof excludedTokenGroupNames[number]; -type TokenGroupName = Exclude; +type TokenGroupName = Exclude; const tokenGroups = Object.fromEntries( - Object.entries(metadata).filter( + Object.entries(metaThemeDefault).filter( ([tokenGroupName]) => !excludedTokenGroupNames.includes( tokenGroupName as ExcludedTokenGroupName, ), ), -) as unknown as Omit; +) as unknown as Omit; type TokenGroupCompletionItems = { [T in TokenGroupName]: CompletionItem[]; @@ -39,19 +43,25 @@ type TokenGroupCompletionItems = { */ const tokenGroupCompletionItems = Object.fromEntries( Object.entries(tokenGroups).map( - ([tokenGroupName, tokenGroup]: [string, MetadataGroup]) => { + ([tokenGroupName, tokenGroup]: [string, MetaTokenGroupShape]) => { const completionItems: CompletionItem[] = Object.entries(tokenGroup).map( - ([tokenName, tokenProperties]): CompletionItem => ({ - label: createVar(tokenName), - insertText: `${createVar(tokenName)}`, - detail: tokenProperties.value, - documentation: tokenProperties.description, - filterText: createVar(tokenName), - kind: - tokenGroupName === 'color' - ? CompletionItemKind.Color - : CompletionItemKind.Variable, - }), + ([tokenName, tokenProperties]): CompletionItem => { + if (!isTokenName(tokenName)) { + throw new Error(`Invalid token name: ${tokenName}`); + } + + return { + label: createVarName(tokenName), + insertText: `${createVarName(tokenName)}`, + detail: tokenProperties.value, + documentation: tokenProperties.description, + filterText: createVarName(tokenName), + kind: + tokenGroupName === 'color' + ? CompletionItemKind.Color + : CompletionItemKind.Variable, + }; + }, ); return [tokenGroupName, completionItems]; From 6b13634b137231bd82845fc6a84a46f8978b082b Mon Sep 17 00:00:00 2001 From: Aaron Casanova <32409546+aaronccasanova@users.noreply.github.com> Date: Mon, 2 Oct 2023 17:27:13 -0700 Subject: [PATCH 19/29] Expose the default theme --- polaris-tokens/scripts/toValues.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/polaris-tokens/scripts/toValues.ts b/polaris-tokens/scripts/toValues.ts index 3c573e96694..42e77ecde52 100644 --- a/polaris-tokens/scripts/toValues.ts +++ b/polaris-tokens/scripts/toValues.ts @@ -31,6 +31,7 @@ export async function toValues() { ]), ), ]), + `export const themeDefault = themes[themeNameDefault];`, `export const isTokenName = createIsTokenName(themes[themeNameDefault]);`, ] .flat() From b0829338bc138210ee4595af1efe868e9c14426b Mon Sep 17 00:00:00 2001 From: Aaron Casanova <32409546+aaronccasanova@users.noreply.github.com> Date: Mon, 2 Oct 2023 17:29:07 -0700 Subject: [PATCH 20/29] Expose the BreakpointsAliasDirection type --- polaris-tokens/src/index.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/polaris-tokens/src/index.ts b/polaris-tokens/src/index.ts index cc68814afd4..6139a6cc81c 100644 --- a/polaris-tokens/src/index.ts +++ b/polaris-tokens/src/index.ts @@ -1,5 +1,7 @@ export {breakpointsAliases} from './themes/base/breakpoints'; +export type {BreakpointsAliasDirection} from './utils'; + export { createVar, createVarName, From 652666e75b03518423ed65056a434f1038377c63 Mon Sep 17 00:00:00 2001 From: Aaron Casanova <32409546+aaronccasanova@users.noreply.github.com> Date: Mon, 2 Oct 2023 17:30:59 -0700 Subject: [PATCH 21/29] Initial Polaris upgrade --- .../ActionList/components/Item/Item.tsx | 5 +- polaris-react/src/components/Frame/Frame.tsx | 80 ++++++++++--------- .../src/components/IndexTable/IndexTable.tsx | 9 ++- .../Modal/components/Dialog/Dialog.tsx | 5 +- .../PopoverOverlay/PopoverOverlay.tsx | 6 +- .../components/ProgressBar/ProgressBar.tsx | 7 +- .../components/ResourceList/ResourceList.tsx | 4 +- polaris-react/src/components/Sheet/Sheet.tsx | 5 +- polaris-react/src/utilities/breakpoints.ts | 6 +- .../sticky-manager/sticky-manager.ts | 10 ++- .../utilities/tests/use-breakpoints.test.tsx | 6 +- polaris-react/src/utilities/use-theme.ts | 6 ++ polaris-react/tests/utilities/breakpoints.tsx | 4 +- 13 files changed, 90 insertions(+), 63 deletions(-) diff --git a/polaris-react/src/components/ActionList/components/Item/Item.tsx b/polaris-react/src/components/ActionList/components/Item/Item.tsx index 2f8aea5d10d..daa1550f588 100644 --- a/polaris-react/src/components/ActionList/components/Item/Item.tsx +++ b/polaris-react/src/components/ActionList/components/Item/Item.tsx @@ -1,5 +1,4 @@ import React, {useRef, useState} from 'react'; -import {zIndex} from '@shopify/polaris-tokens'; import {classNames} from '../../../../utilities/css'; import type {ActionListItemDescriptor} from '../../../../types'; @@ -14,6 +13,7 @@ import {InlineStack} from '../../../InlineStack'; import {Box} from '../../../Box'; import {Tooltip} from '../../../Tooltip'; import {useIsomorphicLayoutEffect} from '../../../../utilities/use-isomorphic-layout-effect'; +import {useTheme} from '../../../../utilities/use-theme'; export type ItemProps = ActionListItemDescriptor; @@ -155,6 +155,7 @@ export function Item({ } export const TruncateText = ({children}: {children: string}) => { + const theme = useTheme(); const textRef = useRef(null); const [isOverflowing, setIsOverflowing] = useState(false); useIsomorphicLayoutEffect(() => { @@ -174,7 +175,7 @@ export const TruncateText = ({children}: {children: string}) => { return isOverflowing ? ( { }; const navigationMarkup = navigation ? ( - - - - - + + + + )} + ) : null; const loadingMarkup = diff --git a/polaris-react/src/components/IndexTable/IndexTable.tsx b/polaris-react/src/components/IndexTable/IndexTable.tsx index db7276dd631..73352705d0c 100644 --- a/polaris-react/src/components/IndexTable/IndexTable.tsx +++ b/polaris-react/src/components/IndexTable/IndexTable.tsx @@ -1,7 +1,7 @@ import React, {useRef, useState, useEffect, useCallback, useMemo} from 'react'; import {SortAscendingMajor, SortDescendingMajor} from '@shopify/polaris-icons'; import {CSSTransition} from 'react-transition-group'; -import {tokens, toPx, motion} from '@shopify/polaris-tokens'; +import {themeDefault, toPx} from '@shopify/polaris-tokens'; import {debounce} from '../../utilities/debounce'; import {useToggle} from '../../utilities/use-toggle'; @@ -39,6 +39,7 @@ import type { Width, TooltipOverlayProps, } from '../Tooltip'; +import {useTheme} from '../../utilities/use-theme'; import {getTableHeadingsBySelector} from './utilities'; import {ScrollContainer, Cell, Row} from './components'; @@ -146,6 +147,8 @@ function IndexTableBase({ hasZebraStriping, ...restProps }: IndexTableBaseProps) { + const theme = useTheme(); + const { loading, bulkSelectState, @@ -546,7 +549,7 @@ function IndexTableBase({ { return typeof window === 'undefined' ? false : window.innerWidth < - parseFloat(toPx(tokens.breakpoints['breakpoints-sm']) ?? ''); + parseFloat(toPx(themeDefault.breakpoints['breakpoints-sm']) ?? ''); }; function getHeadingKey(heading: IndexTableHeading): string { diff --git a/polaris-react/src/components/Modal/components/Dialog/Dialog.tsx b/polaris-react/src/components/Modal/components/Dialog/Dialog.tsx index 1da7b01e6dc..625b5affa23 100644 --- a/polaris-react/src/components/Modal/components/Dialog/Dialog.tsx +++ b/polaris-react/src/components/Modal/components/Dialog/Dialog.tsx @@ -1,7 +1,6 @@ import React, {useContext, useRef, useEffect} from 'react'; import type {SetStateAction, Dispatch} from 'react'; import {Transition, CSSTransition} from 'react-transition-group'; -import {motion} from '@shopify/polaris-tokens'; import {classNames, variationName} from '../../../../utilities/css'; import {focusFirstFocusableNode} from '../../../../utilities/focus'; @@ -11,6 +10,7 @@ import {TrapFocus} from '../../../TrapFocus'; import type {ModalSize} from '../../Modal'; import {Text} from '../../../Text'; import {FrameContext} from '../../../../utilities/frame'; +import {useTheme} from '../../../../utilities/use-theme'; import styles from './Dialog.scss'; @@ -43,6 +43,7 @@ export function Dialog({ hasToasts, ...props }: DialogProps) { + const theme = useTheme(); const containerNode = useRef(null); const frameContext = useContext(FrameContext); let toastMessages; @@ -95,7 +96,7 @@ export function Dialog({ nodeRef={containerNode} mountOnEnter unmountOnExit - timeout={parseInt(motion['motion-duration-200'], 10)} + timeout={parseInt(theme.motion['motion-duration-200'], 10)} onEntered={onEntered} onExited={onExited} > diff --git a/polaris-react/src/components/Popover/components/PopoverOverlay/PopoverOverlay.tsx b/polaris-react/src/components/Popover/components/PopoverOverlay/PopoverOverlay.tsx index 894550d273e..f974c8578ee 100644 --- a/polaris-react/src/components/Popover/components/PopoverOverlay/PopoverOverlay.tsx +++ b/polaris-react/src/components/Popover/components/PopoverOverlay/PopoverOverlay.tsx @@ -1,5 +1,5 @@ import React, {PureComponent, Children, createRef} from 'react'; -import {motion} from '@shopify/polaris-tokens'; +import {themeDefault} from '@shopify/polaris-tokens'; import {findFirstKeyboardFocusableNode} from '../../../../utilities/focus'; import {classNames} from '../../../../utilities/css'; @@ -106,7 +106,9 @@ export class PopoverOverlay extends PureComponent { this.clearTransitionTimeout(); this.enteringTimer = window.setTimeout(() => { this.setState({transitionStatus: TransitionStatus.Entered}); - }, parseInt(motion['motion-duration-100'], 10)); + // Important: This will not update when the active theme changes. + // Update this to `useTheme` once converted to a function component. + }, parseInt(themeDefault.motion['motion-duration-100'], 10)); }); } diff --git a/polaris-react/src/components/ProgressBar/ProgressBar.tsx b/polaris-react/src/components/ProgressBar/ProgressBar.tsx index 73dd5c33801..03edfce82bc 100644 --- a/polaris-react/src/components/ProgressBar/ProgressBar.tsx +++ b/polaris-react/src/components/ProgressBar/ProgressBar.tsx @@ -1,9 +1,9 @@ import React, {useRef} from 'react'; import {CSSTransition} from 'react-transition-group'; -import {motion} from '@shopify/polaris-tokens'; import {classNames, variationName} from '../../utilities/css'; import {useI18n} from '../../utilities/i18n'; +import {useTheme} from '../../utilities/use-theme'; import styles from './ProgressBar.scss'; @@ -44,6 +44,7 @@ export function ProgressBar({ animated: hasAppearAnimation = true, ariaLabelledBy, }: ProgressBarProps) { + const theme = useTheme(); const i18n = useI18n(); const indicatorRef = useRef(null); @@ -63,8 +64,8 @@ export function ProgressBar({ const parsedProgress = parseProgress(progress, warningMessage); const progressBarDuration = hasAppearAnimation - ? motion['motion-duration-500'] - : motion['motion-duration-0']; + ? theme.motion['motion-duration-500'] + : theme.motion['motion-duration-0']; /* eslint-disable @shopify/jsx-no-hardcoded-content */ return ( diff --git a/polaris-react/src/components/ResourceList/ResourceList.tsx b/polaris-react/src/components/ResourceList/ResourceList.tsx index 3b2eed60686..8afcca9ad8b 100644 --- a/polaris-react/src/components/ResourceList/ResourceList.tsx +++ b/polaris-react/src/components/ResourceList/ResourceList.tsx @@ -7,7 +7,7 @@ import React, { Children, } from 'react'; import {EnableSelectionMinor} from '@shopify/polaris-icons'; -import {tokens, toPx} from '@shopify/polaris-tokens'; +import {themeDefault, toPx} from '@shopify/polaris-tokens'; import {debounce} from '../../utilities/debounce'; import {classNames} from '../../utilities/css'; @@ -54,7 +54,7 @@ const isBreakpointsXS = () => { return typeof window === 'undefined' ? false : window.innerWidth < - parseFloat(toPx(tokens.breakpoints['breakpoints-sm']) ?? ''); + parseFloat(toPx(themeDefault.breakpoints['breakpoints-sm']) ?? ''); }; function defaultIdForItem( diff --git a/polaris-react/src/components/Sheet/Sheet.tsx b/polaris-react/src/components/Sheet/Sheet.tsx index a7f8ae7f361..5bbbb6e8a95 100644 --- a/polaris-react/src/components/Sheet/Sheet.tsx +++ b/polaris-react/src/components/Sheet/Sheet.tsx @@ -1,6 +1,5 @@ import React, {useCallback, useRef, useEffect} from 'react'; import {CSSTransition} from 'react-transition-group'; -import {motion} from '@shopify/polaris-tokens'; import {focusFirstFocusableNode} from '../../utilities/focus'; import {useMediaQuery} from '../../utilities/media-query'; @@ -11,6 +10,7 @@ import {Backdrop} from '../Backdrop'; import {TrapFocus} from '../TrapFocus'; import {Portal} from '../Portal'; import {KeypressListener} from '../KeypressListener'; +import {useTheme} from '../../utilities/use-theme'; import styles from './Sheet.scss'; @@ -55,6 +55,7 @@ export function Sheet({ accessibilityLabel, activator, }: SheetProps) { + const theme = useTheme(); const {isNavigationCollapsed} = useMediaQuery(); const container = useRef(null); const activatorRef = useRef(null); @@ -94,7 +95,7 @@ export function Sheet({ classNames={ isNavigationCollapsed ? BOTTOM_CLASS_NAMES : RIGHT_CLASS_NAMES } - timeout={parseInt(motion['motion-duration-300'], 10)} + timeout={parseInt(theme.motion['motion-duration-300'], 10)} in={open} mountOnEnter unmountOnExit diff --git a/polaris-react/src/utilities/breakpoints.ts b/polaris-react/src/utilities/breakpoints.ts index a13de8d365e..accf3edc2b5 100644 --- a/polaris-react/src/utilities/breakpoints.ts +++ b/polaris-react/src/utilities/breakpoints.ts @@ -1,5 +1,5 @@ import {useState} from 'react'; -import {getMediaConditions, breakpoints} from '@shopify/polaris-tokens'; +import {getMediaConditions, themeDefault} from '@shopify/polaris-tokens'; import type { BreakpointsAlias, BreakpointsAliasDirection, @@ -56,7 +56,9 @@ type BreakpointsMatches = { [DirectionAlias in BreakpointsDirectionAlias]: boolean; }; -const breakpointsQueryEntries = getBreakpointsQueryEntries(breakpoints); +const breakpointsQueryEntries = getBreakpointsQueryEntries( + themeDefault.breakpoints, +); function getMatches(defaults?: UseBreakpointsOptions['defaults']) { if (!isServer) { diff --git a/polaris-react/src/utilities/sticky-manager/sticky-manager.ts b/polaris-react/src/utilities/sticky-manager/sticky-manager.ts index 179e96fece1..74727dabf15 100644 --- a/polaris-react/src/utilities/sticky-manager/sticky-manager.ts +++ b/polaris-react/src/utilities/sticky-manager/sticky-manager.ts @@ -1,4 +1,4 @@ -import {space} from '@shopify/polaris-tokens'; +import {themeDefault} from '@shopify/polaris-tokens'; import {debounce} from '../debounce'; import {dataPolarisTopBar, scrollable} from '../../components/shared'; @@ -135,7 +135,13 @@ export class StickyManager { } const stickyOffset = offset - ? this.getOffset(stickyNode) + parseInt(space['space-5'], 10) + ? this.getOffset(stickyNode) + + parseInt( + // Important: This will not update when the active theme changes. + // Update this to `useTheme` once converted to a function component. + themeDefault.space['space-5'], + 10, + ) : this.getOffset(stickyNode); const scrollPosition = scrollTop + stickyOffset; diff --git a/polaris-react/src/utilities/tests/use-breakpoints.test.tsx b/polaris-react/src/utilities/tests/use-breakpoints.test.tsx index b0883efa6ad..9e609b51461 100644 --- a/polaris-react/src/utilities/tests/use-breakpoints.test.tsx +++ b/polaris-react/src/utilities/tests/use-breakpoints.test.tsx @@ -1,13 +1,13 @@ import React from 'react'; import {mount} from 'tests/utilities'; import {matchMedia} from '@shopify/jest-dom-mocks'; -import {breakpoints, getMediaConditions} from '@shopify/polaris-tokens'; +import {themeDefault, getMediaConditions} from '@shopify/polaris-tokens'; import type {BreakpointsTokenName} from '@shopify/polaris-tokens'; import {useBreakpoints, getBreakpointsQueryEntries} from '../breakpoints'; import type {BreakpointsDirectionAlias} from '../breakpoints'; -const mediaConditions = getMediaConditions(breakpoints); +const mediaConditions = getMediaConditions(themeDefault.breakpoints); describe('useBreakpoints', () => { beforeEach(() => { @@ -124,7 +124,7 @@ function setMediaWidth(breakpointsTokenName: BreakpointsTokenName) { describe('getBreakpointsQueryEntries', () => { it('converts breakpoints tokens into entries with direction/alias names', () => { const directionAliases: BreakpointsDirectionAlias[] = - getBreakpointsQueryEntries(breakpoints).map( + getBreakpointsQueryEntries(themeDefault.breakpoints).map( ([directionAlias]) => directionAlias, ); diff --git a/polaris-react/src/utilities/use-theme.ts b/polaris-react/src/utilities/use-theme.ts index 33f0f33d4d2..39c7788036d 100644 --- a/polaris-react/src/utilities/use-theme.ts +++ b/polaris-react/src/utilities/use-theme.ts @@ -19,3 +19,9 @@ export function useTheme() { return theme; } + +export function UseTheme(props: {children(theme: Theme): JSX.Element}) { + const theme = useTheme(); + + return props.children(theme); +} diff --git a/polaris-react/tests/utilities/breakpoints.tsx b/polaris-react/tests/utilities/breakpoints.tsx index b15b24871f4..0636d694408 100644 --- a/polaris-react/tests/utilities/breakpoints.tsx +++ b/polaris-react/tests/utilities/breakpoints.tsx @@ -1,7 +1,7 @@ -import {breakpoints, getMediaConditions} from '@shopify/polaris-tokens'; +import {themeDefault, getMediaConditions} from '@shopify/polaris-tokens'; import type {BreakpointsTokenName} from '@shopify/polaris-tokens'; -const mediaConditions = getMediaConditions(breakpoints); +const mediaConditions = getMediaConditions(themeDefault.breakpoints); export function setMediaWidth(breakpointsTokenName: BreakpointsTokenName) { const aliasDirectionConditions = Object.values( From a804719eac0a9f71e0014626745dc2027be67db1 Mon Sep 17 00:00:00 2001 From: Aaron Casanova <32409546+aaronccasanova@users.noreply.github.com> Date: Mon, 2 Oct 2023 18:01:26 -0700 Subject: [PATCH 22/29] Initial upgrade polaris.shopify.com --- .../pages/api/search/v0/index.tsx | 6 +-- .../pages/api/tokens/v0/[tokens].tsx | 38 ++++++++++++------- .../pages/api/tokens/v0/index.tsx | 12 +++--- polaris.shopify.com/playroom.config.js | 4 +- .../src/components/TokensPage/TokensPage.tsx | 26 ++++++------- polaris.shopify.com/src/types.ts | 4 +- 6 files changed, 51 insertions(+), 39 deletions(-) diff --git a/polaris.shopify.com/pages/api/search/v0/index.tsx b/polaris.shopify.com/pages/api/search/v0/index.tsx index 12d6a3a4b81..8f970c2a270 100644 --- a/polaris.shopify.com/pages/api/search/v0/index.tsx +++ b/polaris.shopify.com/pages/api/search/v0/index.tsx @@ -1,6 +1,6 @@ import type {NextApiRequest, NextApiResponse} from 'next'; import Fuse from 'fuse.js'; -import {metadata, MetadataProperties} from '@shopify/polaris-tokens'; +import {metaThemeDefault, MetaTokenProperties} from '@shopify/polaris-tokens'; import iconMetadata from '@shopify/polaris-icons/metadata'; import { @@ -75,7 +75,7 @@ const getSearchResults = (query?: string) => { }); }); - const {color, border, font, motion, shadow, space, zIndex} = metadata; + const {color, border, font, motion, shadow, space, zIndex} = metaThemeDefault; const tokenGroups = { color, border, @@ -88,7 +88,7 @@ const getSearchResults = (query?: string) => { Object.entries(tokenGroups).forEach(([groupSlug, tokenGroup]) => { Object.entries(tokenGroup).forEach( - ([tokenName, tokenProperties]: [string, MetadataProperties]) => { + ([tokenName, tokenProperties]: [string, MetaTokenProperties]) => { results.push({ id: slugify(`tokens ${tokenName}`), category: 'tokens', diff --git a/polaris.shopify.com/pages/api/tokens/v0/[tokens].tsx b/polaris.shopify.com/pages/api/tokens/v0/[tokens].tsx index dbb26f27df1..1ba4c7b88a4 100644 --- a/polaris.shopify.com/pages/api/tokens/v0/[tokens].tsx +++ b/polaris.shopify.com/pages/api/tokens/v0/[tokens].tsx @@ -1,9 +1,15 @@ -import {createVar, tokens, TokenGroup} from '@shopify/polaris-tokens'; +import type {Theme} from '@shopify/polaris-tokens'; +import { + createVarName, + isTokenName, + themeDefault, +} from '@shopify/polaris-tokens'; import type {NextApiRequest, NextApiResponse} from 'next'; -type TokenGroupKey = keyof typeof tokens; +type TokenGroupName = keyof Theme; +type TokenGroup = Theme[TokenGroupName]; -export const tokenGroupKeys = Object.keys(tokens) as TokenGroupKey[]; +export const tokenGroupNames = Object.keys(themeDefault) as TokenGroupName[]; const formats = ['json', 'css'] as const; @@ -13,22 +19,28 @@ function isFormat(format: unknown): format is Format { return formats.includes(format as Format); } -function isTokenGroupKey(key: unknown): key is TokenGroupKey { - return tokenGroupKeys.includes(key as TokenGroupKey); +function isTokenGroupName(key: unknown): key is TokenGroupName { + return tokenGroupNames.includes(key as TokenGroupName); } /** * Format the token data into: css or json */ -const formatTokenGroup = (tokenGroup: TokenGroup, format: Format) => { +const formatTokenGroup = (tokenGroup: Partial, format: Format) => { const tokenValues = Object.fromEntries( Object.entries(tokenGroup).map(([token, value]) => [token, value]), ); if (format === 'css') { return Object.keys(tokenValues) - .reduce((result, token) => { - const cssVariable = `${createVar(token)}: ${tokenValues[token]};`; + .reduce((result, tokenName) => { + if (!isTokenName(tokenName)) { + throw new Error(`Invalid token name: ${tokenName}`); + } + + const cssVariable = `${createVarName(tokenName)}: ${ + tokenValues[tokenName] + };`; result.push(cssVariable); @@ -45,19 +57,19 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => { if (typeof formatParam === 'string') { const tokenGroupParam = req.query.tokens || ''; - let tokenData: TokenGroup = {}; + let tokenData: Partial = {}; // Determine which list(s) we are querying for based on the token param if (tokenGroupParam === 'all') { - tokenGroupKeys.forEach((group) => { - const tokenGroup = tokens[group]; + tokenGroupNames.forEach((tokenGroupName) => { + const tokenGroup = themeDefault[tokenGroupName]; tokenData = {...tokenData, ...tokenGroup}; }); } - if (isTokenGroupKey(tokenGroupParam)) { - const tokenGroup: TokenGroup = tokens[tokenGroupParam]; + if (isTokenGroupName(tokenGroupParam)) { + const tokenGroup: TokenGroup = themeDefault[tokenGroupParam]; tokenData = {...tokenData, ...tokenGroup}; } diff --git a/polaris.shopify.com/pages/api/tokens/v0/index.tsx b/polaris.shopify.com/pages/api/tokens/v0/index.tsx index 17f6cbb9761..90e62a40606 100644 --- a/polaris.shopify.com/pages/api/tokens/v0/index.tsx +++ b/polaris.shopify.com/pages/api/tokens/v0/index.tsx @@ -1,6 +1,6 @@ import type {NextApiRequest, NextApiResponse} from 'next'; -import {tokenGroupKeys} from './[tokens]'; +import {tokenGroupNames} from './[tokens]'; const getGithubUrl = (file: string) => { const fileName = `${file}.ts`; @@ -66,14 +66,14 @@ const html = ` - ${tokenGroupKeys - .map((tokenGroup) => { - const url = `/api/tokens/v0/${tokenGroup}`; + ${tokenGroupNames + .map((tokenGroupName) => { + const url = `/api/tokens/v0/${tokenGroupName}`; const cssUrl = `${url}?format=css`; return ` - ${tokenGroup} + ${tokenGroupName} ${url} @@ -81,7 +81,7 @@ const html = ` ${cssUrl} - File + File `; diff --git a/polaris.shopify.com/playroom.config.js b/polaris.shopify.com/playroom.config.js index 6fa4814f956..a3ca555f0a4 100644 --- a/polaris.shopify.com/playroom.config.js +++ b/polaris.shopify.com/playroom.config.js @@ -4,7 +4,7 @@ // Workaround: restart the next dev server after each change to the playroom config and associated files. const path = require('path'); -const {breakpoints, toPx} = require('@shopify/polaris-tokens'); +const {themeDefault, toPx} = require('@shopify/polaris-tokens'); const {playroom} = require('./constants'); // Note: We insert a 320 breakpoint to ensure we capture a representation of the @@ -13,7 +13,7 @@ const {playroom} = require('./constants'); // phone size you'll encounter) const breakpointsConfig = [ 320, - ...Object.values(breakpoints) + ...Object.values(themeDefault.breakpoints) .map((value) => +toPx(value).replace('px', '')) .filter((val) => val > 0), ]; diff --git a/polaris.shopify.com/src/components/TokensPage/TokensPage.tsx b/polaris.shopify.com/src/components/TokensPage/TokensPage.tsx index 535b2ba0864..e10b014dfcb 100644 --- a/polaris.shopify.com/src/components/TokensPage/TokensPage.tsx +++ b/polaris.shopify.com/src/components/TokensPage/TokensPage.tsx @@ -1,5 +1,5 @@ import styles from './TokensPage.module.scss'; -import {MetadataGroup, metadata as allTokens} from '@shopify/polaris-tokens'; +import {MetaTokenGroupShape, metaThemeDefault} from '@shopify/polaris-tokens'; import {Status, TokenPropertiesWithName} from '../../types'; import TokenList from '../TokenList'; import Link from 'next/link'; @@ -78,7 +78,7 @@ const navItems: NavItem[] = [ function tokensToFilteredArray( filter: string, - tokenGroup: MetadataGroup, + tokenGroup: MetaTokenGroupShape, ): TokenPropertiesWithName[] { return Object.entries(tokenGroup) .filter(([name]) => { @@ -94,17 +94,17 @@ function TokensPage({tokenGroup}: Props) { const router = useRouter(); const tokens = { - border: tokensToFilteredArray(filter, allTokens.border), - breakpoints: tokensToFilteredArray(filter, allTokens.breakpoints), - color: tokensToFilteredArray(filter, allTokens.color), - font: tokensToFilteredArray(filter, allTokens.font), - height: tokensToFilteredArray(filter, allTokens.height), - motion: tokensToFilteredArray(filter, allTokens.motion), - shadow: tokensToFilteredArray(filter, allTokens.shadow), - space: tokensToFilteredArray(filter, allTokens.space), - text: tokensToFilteredArray(filter, allTokens.text), - width: tokensToFilteredArray(filter, allTokens.width), - zIndex: tokensToFilteredArray(filter, allTokens.zIndex), + border: tokensToFilteredArray(filter, metaThemeDefault.border), + breakpoints: tokensToFilteredArray(filter, metaThemeDefault.breakpoints), + color: tokensToFilteredArray(filter, metaThemeDefault.color), + font: tokensToFilteredArray(filter, metaThemeDefault.font), + height: tokensToFilteredArray(filter, metaThemeDefault.height), + motion: tokensToFilteredArray(filter, metaThemeDefault.motion), + shadow: tokensToFilteredArray(filter, metaThemeDefault.shadow), + space: tokensToFilteredArray(filter, metaThemeDefault.space), + text: tokensToFilteredArray(filter, metaThemeDefault.text), + width: tokensToFilteredArray(filter, metaThemeDefault.width), + zIndex: tokensToFilteredArray(filter, metaThemeDefault.zIndex), }; const keyframeStyles = tokens['motion'] diff --git a/polaris.shopify.com/src/types.ts b/polaris.shopify.com/src/types.ts index 390b900a89b..0f395a194a7 100644 --- a/polaris.shopify.com/src/types.ts +++ b/polaris.shopify.com/src/types.ts @@ -1,4 +1,4 @@ -import type {MetadataProperties} from '@shopify/polaris-tokens'; +import type {MetaTokenProperties} from '@shopify/polaris-tokens'; import type {Icon} from '@shopify/polaris-icons/metadata'; import type {MDXRemoteSerializeResult} from 'next-mdx-remote'; @@ -96,7 +96,7 @@ export type MarkdownFile = { readme: string; }; -export interface TokenPropertiesWithName extends MetadataProperties { +export interface TokenPropertiesWithName extends MetaTokenProperties { name: string; } From 01a31e324ccacd22b340a3c43b618593c1d671ab Mon Sep 17 00:00:00 2001 From: Aaron Casanova <32409546+aaronccasanova@users.noreply.github.com> Date: Mon, 2 Oct 2023 18:11:37 -0700 Subject: [PATCH 23/29] Upgrade stylelint-polaris --- stylelint-polaris/index.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/stylelint-polaris/index.js b/stylelint-polaris/index.js index 26296b8dcea..cabbf1689ba 100644 --- a/stylelint-polaris/index.js +++ b/stylelint-polaris/index.js @@ -1,7 +1,7 @@ const { - getCustomPropertyNames, createVar, - tokens, + getThemeVarNames, + themeDefault, } = require('@shopify/polaris-tokens'); const disallowedUnits = [ @@ -117,7 +117,7 @@ const stylelintPolarisCoverageOptions = { '/.+/': [ // Note: Order is important // This pattern allows use of `--p-*` custom properties that are valid Polaris tokens - ...getCustomPropertyNames(tokens), + ...getThemeVarNames(themeDefault), // This pattern flags unknown `--p-*` custom properties or usage of deprecated `--pc-*` custom properties private to polaris-react /--(?!(p|pc)-).+/, ], @@ -405,8 +405,8 @@ const stylelintPolarisCoverageOptions = { { 'declaration-property-value-allowed-list': [ { - 'z-index': Object.keys(tokens.zIndex).map( - (token) => `var(${createVar(token)})`, + 'z-index': Object.keys(themeDefault.zIndex).map((tokenName) => + createVar(tokenName), ), }, ], From d9d4d45cf95366ffca16826e6cc6fa1abb0f58e0 Mon Sep 17 00:00:00 2001 From: Aaron Casanova <32409546+aaronccasanova@users.noreply.github.com> Date: Tue, 3 Oct 2023 08:28:27 -0700 Subject: [PATCH 24/29] Fix Polaris tokens tests --- polaris-tokens/scripts/toStyleSheet.ts | 15 ++++++++++----- polaris-tokens/tests/utilities.test.js | 6 +++--- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/polaris-tokens/scripts/toStyleSheet.ts b/polaris-tokens/scripts/toStyleSheet.ts index 05db17377ce..9c0a07a3443 100644 --- a/polaris-tokens/scripts/toStyleSheet.ts +++ b/polaris-tokens/scripts/toStyleSheet.ts @@ -1,7 +1,11 @@ import fs from 'fs'; import path from 'path'; -import type {MetaThemeShape, MetaTokenGroupShape} from '../src/themes/types'; +import type { + MetaThemeShape, + MetaTokenGroupShape, + TokenName, +} from '../src/themes/types'; import {metaThemePartials, metaThemeDefault} from '../src/themes'; import {themeNameDefault} from '../src/themes/constants'; import {createThemeSelector, isTokenName} from '../src/themes/utils'; @@ -23,10 +27,11 @@ export function getMetaThemeDecls(metaTheme: MetaThemeShape) { /** Creates CSS declarations from a token group. */ export function getMetaTokenGroupDecls(metaTokenGroup: MetaTokenGroupShape) { return Object.entries(metaTokenGroup) - .map(([tokenName, {value}]) => { - if (!isTokenName(tokenName)) { - throw new Error(`Invalid token name: ${tokenName}`); - } + .map((entry) => { + const [tokenName, {value}] = entry as [ + TokenName, + MetaTokenGroupShape[string], + ]; return tokenName.startsWith('motion-keyframes') ? `${createVarName(tokenName)}:p-${tokenName};` diff --git a/polaris-tokens/tests/utilities.test.js b/polaris-tokens/tests/utilities.test.js index dc8d6fdcaee..4bea98d5246 100644 --- a/polaris-tokens/tests/utilities.test.js +++ b/polaris-tokens/tests/utilities.test.js @@ -3,7 +3,7 @@ import { createVarName, getThemeVarNames, getKeyframeNames, - tokensToRems, + tokenGroupToRems, toPx, toEm, toRem, @@ -78,7 +78,7 @@ describe('getKeyframeNames', () => { }); }); -describe('tokensToRems', () => { +describe('tokenGroupToRems', () => { it("converts a token group's value from px to rems", () => { const tokenGroup = { foo: {value: '12px'}, @@ -86,7 +86,7 @@ describe('tokensToRems', () => { baz: {value: '16px 32px'}, }; - const result = tokensToRems(tokenGroup); + const result = tokenGroupToRems(tokenGroup); expect(result.foo.value).toBe('0.75rem'); expect(result.bar.value).toBe('1rem'); From b81487b85fb948449a8d90cf9a353d2316a714d6 Mon Sep 17 00:00:00 2001 From: Aaron Casanova <32409546+aaronccasanova@users.noreply.github.com> Date: Tue, 3 Oct 2023 08:51:52 -0700 Subject: [PATCH 25/29] Fix polaris-migrator type-check --- .../src/migrations/v9-scss-replace-color/transform.ts | 5 +++-- polaris-migrator/src/utilities/sass.ts | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/polaris-migrator/src/migrations/v9-scss-replace-color/transform.ts b/polaris-migrator/src/migrations/v9-scss-replace-color/transform.ts index 54d9d3ce508..106e7978b99 100644 --- a/polaris-migrator/src/migrations/v9-scss-replace-color/transform.ts +++ b/polaris-migrator/src/migrations/v9-scss-replace-color/transform.ts @@ -2,7 +2,6 @@ import type {FileInfo, API, Options} from 'jscodeshift'; import type {Plugin} from 'postcss'; import postcss from 'postcss'; import valueParser from 'postcss-value-parser'; -import {createVar} from '@shopify/polaris-tokens'; import type {NamespaceOptions} from '../../utilities/sass'; import { @@ -239,5 +238,7 @@ const propertyMaps = { }; const polarisCustomPropertyRegEx = new RegExp( - Object.keys(tokenColors).map(createVar).join('|'), + Object.keys(tokenColors) + .map((tokenName) => `--p-${tokenName}`) + .join('|'), ); diff --git a/polaris-migrator/src/utilities/sass.ts b/polaris-migrator/src/utilities/sass.ts index 40fdde08445..d6c3f9f4f64 100644 --- a/polaris-migrator/src/utilities/sass.ts +++ b/polaris-migrator/src/utilities/sass.ts @@ -18,14 +18,14 @@ import type { Dimension, } from 'postcss-value-parser'; import valueParser from 'postcss-value-parser'; -import {toPx, getCustomPropertyNames, tokens} from '@shopify/polaris-tokens'; +import {toPx, getThemeVarNames, themeDefault} from '@shopify/polaris-tokens'; import {POLARIS_MIGRATOR_COMMENT} from './constants'; const defaultNamespace = ''; const polarisCustomPropertyRegEx = new RegExp( - getCustomPropertyNames(tokens).join('|'), + getThemeVarNames(themeDefault).join('|'), ); function getNamespace(options?: NamespaceOptions) { From 38fc668502ba5638f6363425f0001491875293cd Mon Sep 17 00:00:00 2001 From: Aaron Casanova <32409546+aaronccasanova@users.noreply.github.com> Date: Tue, 3 Oct 2023 09:17:53 -0700 Subject: [PATCH 26/29] Fix type-check --- polaris-migrator/src/utilities/sass.ts | 4 ++-- .../plugins/custom-property-allowed-list/index.test.js | 9 +++------ 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/polaris-migrator/src/utilities/sass.ts b/polaris-migrator/src/utilities/sass.ts index d6c3f9f4f64..07c2f437031 100644 --- a/polaris-migrator/src/utilities/sass.ts +++ b/polaris-migrator/src/utilities/sass.ts @@ -24,7 +24,7 @@ import {POLARIS_MIGRATOR_COMMENT} from './constants'; const defaultNamespace = ''; -const polarisCustomPropertyRegEx = new RegExp( +const themeVarNamesRegExp = new RegExp( getThemeVarNames(themeDefault).join('|'), ); @@ -325,7 +325,7 @@ export function isTransformableDuration( export function isPolarisVar(node: Node): boolean { return ( isSassFunction('var', node) && - polarisCustomPropertyRegEx.test(node.nodes?.[0]?.value ?? '') + themeVarNamesRegExp.test(node.nodes?.[0]?.value ?? '') ); } diff --git a/stylelint-polaris/plugins/custom-property-allowed-list/index.test.js b/stylelint-polaris/plugins/custom-property-allowed-list/index.test.js index 7357ac5cb70..e2b78f0660c 100644 --- a/stylelint-polaris/plugins/custom-property-allowed-list/index.test.js +++ b/stylelint-polaris/plugins/custom-property-allowed-list/index.test.js @@ -1,8 +1,8 @@ -const {getCustomPropertyNames, tokens} = require('@shopify/polaris-tokens'); +const {getThemeVarNames, themeDefault} = require('@shopify/polaris-tokens'); const {messages, ruleName} = require('.'); -const polarisCustomPropertyNames = getCustomPropertyNames(tokens); +const themeVarNames = getThemeVarNames(themeDefault); /* --p-* Tokens are to be defined in polaris-tokens. @@ -20,10 +20,7 @@ const config = [ { allowedProperties: [allowedCustomPropertyNames], allowedValues: { - '/.+/': [ - ...polarisCustomPropertyNames, - invalidOrDeprecatedPrivateCustomPropertyNames, - ], + '/.+/': [...themeVarNames, invalidOrDeprecatedPrivateCustomPropertyNames], }, }, ]; From da321eaef160a043d71943f342bd33a2a78f9332 Mon Sep 17 00:00:00 2001 From: Aaron Casanova <32409546+aaronccasanova@users.noreply.github.com> Date: Tue, 3 Oct 2023 10:06:27 -0700 Subject: [PATCH 27/29] Add theme context to PolarisTestProvider --- .../PolarisTestProvider.tsx | 49 +++++++++++-------- 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/polaris-react/src/components/PolarisTestProvider/PolarisTestProvider.tsx b/polaris-react/src/components/PolarisTestProvider/PolarisTestProvider.tsx index f5e5e954823..f232423d7c5 100644 --- a/polaris-react/src/components/PolarisTestProvider/PolarisTestProvider.tsx +++ b/polaris-react/src/components/PolarisTestProvider/PolarisTestProvider.tsx @@ -1,4 +1,6 @@ import React, {useMemo, Fragment, StrictMode} from 'react'; +import type {ThemeName} from '@shopify/polaris-tokens'; +import {themeNameDefault} from '@shopify/polaris-tokens'; import {PortalsManager} from '../PortalsManager'; import {FocusManager} from '../FocusManager'; @@ -19,6 +21,7 @@ import type {LinkLikeComponent} from '../../utilities/link'; import {FeaturesContext} from '../../utilities/features'; import type {FeaturesConfig} from '../../utilities/features'; import {EphemeralPresenceManager} from '../EphemeralPresenceManager'; +import {ThemeContext, getTheme} from '../../utilities/use-theme'; type FrameContextType = NonNullable>; type MediaQueryContextType = NonNullable< @@ -36,6 +39,7 @@ export interface WithPolarisTestProviderOptions { link?: LinkLikeComponent; mediaQuery?: Partial; features?: FeaturesConfig; + theme?: ThemeName; // Contexts provided by Frame frame?: Partial; } @@ -58,6 +62,7 @@ export function PolarisTestProvider({ mediaQuery, features, frame, + theme = themeNameDefault, }: PolarisTestProviderProps) { const Wrapper = strict ? StrictMode : Fragment; const intl = useMemo(() => new I18n(i18n || {}), [i18n]); @@ -71,27 +76,29 @@ export function PolarisTestProvider({ return ( - - - - - - - - - - - {children} - - - - - - - - - - + + + + + + + + + + + + {children} + + + + + + + + + + + ); } From 2ef321219f642a83bbbd745cd6a99da1b7eb314f Mon Sep 17 00:00:00 2001 From: Aaron Casanova <32409546+aaronccasanova@users.noreply.github.com> Date: Tue, 3 Oct 2023 11:06:00 -0700 Subject: [PATCH 28/29] Adjust migration guide for Polaris tokens updates --- .../migrating-from-v11-to-v12.md | 36 +++++++++++++++---- 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/polaris.shopify.com/content/version-guides/migrating-from-v11-to-v12.md b/polaris.shopify.com/content/version-guides/migrating-from-v11-to-v12.md index e5f3eb2e1db..334a31c903e 100644 --- a/polaris.shopify.com/content/version-guides/migrating-from-v11-to-v12.md +++ b/polaris.shopify.com/content/version-guides/migrating-from-v11-to-v12.md @@ -881,17 +881,16 @@ git commit -m "Manually migrate X custom properties from Polaris v11 to v12" npx stylelint ``` -### Token utility updates +### `@shopify/polaris-tokens` updates #### Renames - `getCustomPropertyNames` renamed to `getThemeVarNames` +- `createVar` renamed to `createVarName` -#### Type deprecations +#### Deprecations -- `Tokens` type is now deprecated, use the `Theme` type instead - -#### Utility deprecations +##### Deprecated Utilities If you are using these utilities, feel free to copy them from v11 into your own codebase. @@ -903,7 +902,32 @@ If you are using these utilities, feel free to copy them from v11 into your own - `removeMetadata` - `toEm` - `tokensToRems` -- `toJSON` + +##### Deprecated Types + +- `Tokens` type is now deprecated, use the `Theme` type instead + +##### Deprecated all JSON exports + +- `@shopify/polaris-tokens/json/border.json` +- `@shopify/polaris-tokens/json/breakpoints.json` +- `@shopify/polaris-tokens/json/color.json` +- `@shopify/polaris-tokens/json/font.json` +- `@shopify/polaris-tokens/json/height.json` +- `@shopify/polaris-tokens/json/motion.json` +- `@shopify/polaris-tokens/json/shadow.json` +- `@shopify/polaris-tokens/json/space.json` +- `@shopify/polaris-tokens/json/text.json` +- `@shopify/polaris-tokens/json/width.json` +- `@shopify/polaris-tokens/json/zIndex.json` + +If you are using these exports, update the implementation to import `themes` and `JSON.stringify` the theme you need. + +```diff +- const color = require('@shopify/polaris-tokens/json/color.json'); ++ const {themes} = require('@shopify/polaris-tokens'); ++ const color = JSON.stringify(themes.light.color); +``` ## Manual updates and fixes From 84286226959fbf20e6dc6da6d21b78e078c151ea Mon Sep 17 00:00:00 2001 From: Aaron Casanova <32409546+aaronccasanova@users.noreply.github.com> Date: Tue, 3 Oct 2023 12:17:11 -0700 Subject: [PATCH 29/29] Add changeset entry --- .changeset/gentle-suns-relax.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/gentle-suns-relax.md diff --git a/.changeset/gentle-suns-relax.md b/.changeset/gentle-suns-relax.md new file mode 100644 index 00000000000..8feb0399b49 --- /dev/null +++ b/.changeset/gentle-suns-relax.md @@ -0,0 +1,5 @@ +--- +'@shopify/polaris-tokens': major +--- + +Deprecated a collection of types, utils, and JSON exports