-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Add migration to replace-typography-declarations
#7335
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 2 commits
Commits
Show all changes
24 commits
Select commit
Hold shift + click to select a range
158b6e6
Initial replace-typography-declarations migration
aaronccasanova dcbe2b8
docs: Add changeset entry
aaronccasanova 3bf8eaf
Add support for migrating basic rem function calls
aaronccasanova 8106a92
Remove unused imports
aaronccasanova 2577a9f
Merge branch 'main' of https://github.com/Shopify/polaris into replac…
aaronccasanova 77c5efe
Fix merge conflict errors
aaronccasanova 99d424e
Add with-namespace tests
aaronccasanova 91f1c4c
Update changeset entry
aaronccasanova c4cd95d
Add replaceDecl utility to reduce duplicate handler logic
aaronccasanova 3763cf8
Make Polaris migrator comment generic
aaronccasanova 40f3881
Add utility to getFunctionArgs
aaronccasanova abd06d4
Add support for the legacy font-size() function
aaronccasanova 88c4a26
Rearchitect migration to reduce duplicate comment logic
aaronccasanova 56c2329
Add support for the legacy line-height() function
aaronccasanova fdc6e12
Merge branch 'main' of https://github.com/Shopify/polaris into replac…
aaronccasanova dfa9668
Remove replaceDecl utility
aaronccasanova 58a4512
Merge branch 'main' of https://github.com/Shopify/polaris into replac…
aaronccasanova b895e2c
Restructure migration to only parse values of target declarations
aaronccasanova 0cac336
Ignore global values
aaronccasanova 9bfdb6b
Update polaris-migrator/src/migrations/replace-typography-declaration…
aaronccasanova 8322f0c
Update polaris-migrator/src/migrations/replace-typography-declaration…
aaronccasanova debb469
Add rem() support to the line-height handler
aaronccasanova 46b1cce
Update line-height test lengths
aaronccasanova 1487243
Add replace-typography-declarations docs
aaronccasanova File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| '@shopify/polaris-migrator': patch | ||
| --- | ||
|
|
||
| Add migration to `replace-typography-declarations` | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
192 changes: 192 additions & 0 deletions
192
...igrator/src/migrations/replace-typography-declarations/replace-typography-declarations.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,192 @@ | ||
| import type {FileInfo, API, Options} from 'jscodeshift'; | ||
| import postcss, {Declaration, Plugin} from 'postcss'; | ||
| import valueParser from 'postcss-value-parser'; | ||
| import {toPx} from '@shopify/polaris-tokens'; | ||
|
|
||
| import { | ||
| NamespaceOptions, | ||
| namespace, | ||
| isTransformableLength, | ||
| hasSassFunction, | ||
| isSassFunction, | ||
| } from '../../utilities/sass'; | ||
| import {isKeyof} from '../../utilities/type-guards'; | ||
|
|
||
| export default function replaceTypographyDeclarations( | ||
| fileInfo: FileInfo, | ||
| _: API, | ||
| options: Options, | ||
| ) { | ||
| return postcss(plugin(options)).process(fileInfo.source, { | ||
| syntax: require('postcss-scss'), | ||
| }).css; | ||
| } | ||
|
|
||
| const processed = Symbol('processed'); | ||
|
|
||
| interface PluginOptions extends Options, NamespaceOptions {} | ||
|
|
||
| const plugin = (options: PluginOptions = {}): Plugin => { | ||
| const namespacedFontFamily = namespace('font-family', options); | ||
|
|
||
| return { | ||
| postcssPlugin: 'replace-typography-declarations', | ||
| Declaration: { | ||
| 'font-family': createHandleFontFamily(namespacedFontFamily), | ||
| 'font-size': handleFontSize, | ||
| 'font-weight': handleFontWeight, | ||
| 'line-height': handleFontLineHeight, | ||
| }, | ||
| }; | ||
| }; | ||
|
|
||
| const fontFamilyMap = { | ||
| '': '--p-font-family-sans', | ||
| base: '--p-font-family-sans', | ||
| monospace: '--p-font-family-mono', | ||
| }; | ||
|
|
||
| const fontSizeMap = { | ||
| '12px': '--p-font-size-75', | ||
| '14px': '--p-font-size-100', | ||
| '16px': '--p-font-size-200', | ||
| '20px': '--p-font-size-300', | ||
| '24px': '--p-font-size-400', | ||
| '28px': '--p-font-size-500', | ||
| '32px': '--p-font-size-600', | ||
| '40px': '--p-font-size-700', | ||
| }; | ||
|
|
||
| const fontLineHeightMap = { | ||
| '16px': '--p-font-line-height-1', | ||
| '20px': '--p-font-line-height-2', | ||
| '24px': '--p-font-line-height-3', | ||
| '28px': '--p-font-line-height-4', | ||
| '32px': '--p-font-line-height-5', | ||
| '40px': '--p-font-line-height-6', | ||
| '48px': '--p-font-line-height-7', | ||
| }; | ||
|
|
||
| const fontWeightMap = { | ||
| 400: '--p-font-weight-regular', | ||
| 500: '--p-font-weight-medium', | ||
| 600: '--p-font-weight-semibold', | ||
| 700: '--p-font-weight-bold', | ||
| // https://drafts.csswg.org/css-fonts-3/#propdef-font-weight | ||
| // 100 - Thin | ||
| // 200 - Extra Light (Ultra Light) | ||
| // 300 - Light | ||
| // 400 - Normal | ||
| normal: '--p-font-weight-regular', | ||
| // 500 - Medium | ||
| // 600 - Semi Bold (Demi Bold) | ||
| // 700 - Bold | ||
| bold: '--p-font-weight-bold', | ||
| // 800 - Extra Bold (Ultra Bold) | ||
| // 900 - Black (Heavy) | ||
| }; | ||
|
|
||
| function createHandleFontFamily(namespacedFontFamily: string) { | ||
| return (decl: Declaration): void => { | ||
| // @ts-expect-error - Skip if processed so we don't process it again | ||
| if (decl[processed]) return; | ||
|
|
||
| const parsedValue = valueParser(decl.value); | ||
|
|
||
| if (!hasSassFunction(namespacedFontFamily, parsedValue)) return; | ||
|
|
||
| parsedValue.walk((node) => { | ||
| if (!isSassFunction(namespacedFontFamily, node)) return; | ||
|
|
||
| const fontFamily = node.nodes[0]?.value ?? ''; | ||
|
|
||
| if (!isKeyof(fontFamilyMap, fontFamily)) return; | ||
|
|
||
| const fontFamilyCustomProperty = fontFamilyMap[fontFamily]; | ||
|
|
||
| node.value = 'var'; | ||
| node.nodes = [ | ||
| { | ||
| type: 'word', | ||
| value: fontFamilyCustomProperty, | ||
| sourceIndex: node.nodes[0]?.sourceIndex ?? 0, | ||
| sourceEndIndex: fontFamilyCustomProperty.length, | ||
| }, | ||
| ]; | ||
| }); | ||
|
|
||
| decl.value = parsedValue.toString(); | ||
|
|
||
| // @ts-expect-error - Mark the declaration as processed | ||
| decl[processed] = true; | ||
| }; | ||
| } | ||
|
|
||
| function handleFontSize(decl: Declaration): void { | ||
| // @ts-expect-error - Skip if processed so we don't process it again | ||
| if (decl[processed]) return; | ||
|
|
||
| const parsedValue = valueParser(decl.value); | ||
| const fontSize = parsedValue.nodes[0]; | ||
|
|
||
| if (parsedValue.nodes.length !== 1 || fontSize.type !== 'word') { | ||
| return; | ||
| } | ||
|
|
||
| const dimension = valueParser.unit(fontSize.value); | ||
|
|
||
| if (!isTransformableLength(dimension)) return; | ||
|
|
||
| const dimensionInPx = toPx(`${dimension.number}${dimension.unit}`); | ||
|
|
||
| if (!isKeyof(fontSizeMap, dimensionInPx)) return; | ||
|
|
||
| decl.value = `var(${fontSizeMap[dimensionInPx]})`; | ||
|
|
||
| // @ts-expect-error - Mark the declaration as processed | ||
| decl[processed] = true; | ||
| } | ||
|
|
||
| function handleFontWeight(decl: Declaration): void { | ||
| // @ts-expect-error - Skip if processed so we don't process it again | ||
| if (decl[processed]) return; | ||
|
|
||
| const parsedValue = valueParser(decl.value); | ||
| const fontWeight = parsedValue.nodes[0]; | ||
|
|
||
| if (parsedValue.nodes.length !== 1 || fontWeight.type !== 'word') { | ||
| return; | ||
| } | ||
|
|
||
| if (!isKeyof(fontWeightMap, fontWeight.value)) return; | ||
|
|
||
| decl.value = `var(${fontWeightMap[fontWeight.value]})`; | ||
|
|
||
| // @ts-expect-error - Mark the declaration as processed | ||
| decl[processed] = true; | ||
| } | ||
|
|
||
| function handleFontLineHeight(decl: Declaration): void { | ||
| // @ts-expect-error - Skip if processed so we don't process it again | ||
| if (decl[processed]) return; | ||
|
|
||
| const parsedValue = valueParser(decl.value); | ||
| const lineHeight = parsedValue.nodes[0]; | ||
|
|
||
| if (parsedValue.nodes.length !== 1 || lineHeight.type !== 'word') { | ||
| return; | ||
| } | ||
|
|
||
| const dimension = valueParser.unit(lineHeight.value); | ||
|
|
||
| if (!isTransformableLength(dimension)) return; | ||
|
|
||
| const dimensionInPx = toPx(`${dimension.number}${dimension.unit}`); | ||
|
|
||
| if (!isKeyof(fontLineHeightMap, dimensionInPx)) return; | ||
|
|
||
| decl.value = `var(${fontLineHeightMap[dimensionInPx]})`; | ||
|
|
||
| // @ts-expect-error - Mark the declaration as processed | ||
| decl[processed] = true; | ||
| } |
29 changes: 29 additions & 0 deletions
29
...grations/replace-typography-declarations/tests/replace-typography-declarations.input.scss
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| .font-family { | ||
| font-family: sans-serif; | ||
| font-family: font-family(); | ||
| font-family: font-family(base); | ||
| font-family: font-family(monospace); | ||
| } | ||
|
|
||
| .font-size { | ||
| font-size: 10px; | ||
| font-size: 12px; | ||
| font-size: 1rem; | ||
| font-size: 1em; | ||
| } | ||
|
|
||
| .font-weight { | ||
| font-weight: 300; | ||
| font-weight: 400; | ||
| font-weight: 700; | ||
| font-weight: normal; | ||
| font-weight: bold; | ||
| font-weight: 400 !important; | ||
| font-weight: 400 + $var; | ||
| } | ||
|
|
||
| .font-line-height { | ||
| line-height: 10px; | ||
| line-height: 16px; | ||
| line-height: 1rem; | ||
| } |
29 changes: 29 additions & 0 deletions
29
...rations/replace-typography-declarations/tests/replace-typography-declarations.output.scss
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| .font-family { | ||
| font-family: sans-serif; | ||
| font-family: var(--p-font-family-sans); | ||
| font-family: var(--p-font-family-sans); | ||
| font-family: var(--p-font-family-mono); | ||
| } | ||
|
|
||
| .font-size { | ||
| font-size: 10px; | ||
| font-size: var(--p-font-size-75); | ||
| font-size: var(--p-font-size-200); | ||
| font-size: 1em; | ||
| } | ||
|
|
||
| .font-weight { | ||
| font-weight: 300; | ||
| font-weight: var(--p-font-weight-regular); | ||
| font-weight: var(--p-font-weight-bold); | ||
| font-weight: var(--p-font-weight-regular); | ||
| font-weight: var(--p-font-weight-bold); | ||
| font-weight: var(--p-font-weight-regular) !important; | ||
| font-weight: 400 + $var; | ||
| } | ||
|
|
||
| .font-line-height { | ||
| line-height: 10px; | ||
| line-height: var(--p-font-line-height-1); | ||
| line-height: var(--p-font-line-height-1); | ||
| } |
12 changes: 12 additions & 0 deletions
12
.../migrations/replace-typography-declarations/tests/replace-typography-declarations.test.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| import {check} from '../../../utilities/testUtils'; | ||
|
|
||
| const migration = 'replace-typography-declarations'; | ||
| const fixtures = ['replace-typography-declarations']; | ||
|
|
||
| for (const fixture of fixtures) { | ||
| check(__dirname, { | ||
| fixture, | ||
| migration, | ||
| extension: 'scss', | ||
| }); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| export function isKeyof<T extends {[key: string]: any}>( | ||
| obj: T, | ||
| key: PropertyKey | undefined, | ||
| ): key is keyof T { | ||
| return Object.keys(obj).includes(key as string); | ||
| } |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.