Follow the guidelines below to keep your code up-to-date with the latest version of SWAN.
Migration
Check out the migration docs for v3 here: v2 -> v3
Guidelines
Review the Changelog
All notable changes to SWAN are described on the Changelog page. We ask you to please visit that page and have a quick look at all the changes (specifically Design changes and New features), as these may answer your questions about any visual changes that you may observe after migrating to a major version.
Once you’re familiar with the changes you can expect, update your code by following the steps below.
Run codemods
A codemod is a powerful script that replaces the need for manually performing code changes. To make both major and minor upgrades easier, we offer codemods to automate as many of the code changes as possible.
Refer to the Codemods page for instructions.
Implement manual code changes
If you are migrating to a major version, it is likely that there are significant changes that couldn’t be automated with a codemod.
Refer to the tab for that migration for specific instructions. For example, if you are migrating from version 2 to version 3, refer to the v2 → v3 tab.
SWAN x elev8
SWAN is a major delivery mechanism for some of the larger goals of the elev8 initiative. As such, there are a few key milestones of SWAN to be aware of.
See more information on elev8 planning and how SWAN will roll out elev8.
v2 Minor versions
To allow teams the maximum time to update token usage, we've released our new token architecture in parallel to the existing one. Codemods exist to support this upgrade, and you may see small visual changes that require VQA, as mentioned below. However, none of these changes are breaking; running the codemods prior to v3.0 just better prepares you for the v3.0 upgrade.
v3.0 Major version
This is a large update that contains many API-breaking changes, and a few visual changes. Namely, there are many removals around legacy props, components, tokens, and otherwise. This version also removes the old token architecture, meaning if you are still using old tokens, you will be forced to upgrade now.
Visually, there are minor changes to space and color, but you should expect larger changes to typography if you were not already using the x
scale, originally introduced in SWAN 1.3.
v3.3 Minor version
Acting as a counterpart to v3.0, this is the visual language update, containing many visual changes that will require VQA. Visual language updates include changes to color, typography, shape, space, and more.
Although there are many visual changes, the goal for this release has always been no required engineering effort. Designers have tested these changes early but Engineering may be needed to help fix things found in VQA.
Codemods
SWAN v3 is our first major version to be supported by the new SWAN-CLI tool! We've written a ton of codemods to make your life easier and speed up the upgrade process.
Before running codemods, please read these guidelines carefully!
Check what version of SWAN your codebase is using. Each codemod is tied to a major.minor.patch
version of SWAN. This is the minimum version your codebase must be on before you can run that codemod, because it may reference new features/functionality that were introduced in that version.
Run codemods in small batches. By running a few codemods at a time, you can more easily track, test, and revert changes. For example, it is recommended to run typography, color, and other token related codemods by themselves, since they are likely to make a lot of changes that need careful review.
Run codemods tied to major versions in isolation. Codemods tied to major versions are not guaranteed to be idempotent - they may not yield the same results if run multiple times. For example, the v3.0.0 codemod "migrate spacing prop values" CAN ONLY RUN ONCE. We change the values of some of our spacing props, and every sebsequent execution will make your UI spacing will get larger and larger.
Work with your designer to VQA the changes after you run the codemods. Not every codemod is an exact 1:1 replacement. For example, the codemods to move to the new typography scale may introduce slight differences in font size. There are also significantly fewer colors available in SWAN 3.0 than before, so the codemods to migrate color tokens will convert multiple legacy tokens to the same new color token, introducing some visual differences.
If you find a issue with codemods, but you can easily upgrade manually, do so. It takes time to fix codemods, and we may not be able to even fix issues that are spotted. Anything that is being performed by a codemod should be documented on the docsite. Most likely on the main migration page listed above, but more specialised info is documented on relevant pages, such as component pages. If you can't find the information, please ask us, so we can update the documentation or point you to the right place.
Please see Codemods for more information.
Deprecations
SWAN v3 removes a lot of bloat that we've been carrying for multiple versions, including some decisions made back in Visage. As such, SWAN v3 removes many deprecated components, props, etc.
You can see the full list on our Deprecation Roadmap.
Find more information on tokens below.
Tokens
SWAN v3 includes a major overhaul of our design token architecture.
For more detailed information on the new token architecture, see: Tokens
A list of all tokens can be found here: All Tokens
Importing
We’ve drastically reduced the inconsistency across supported languages. Many JS-only objects are removed, and SCSS no longer has special ‘non-literal value’ tokens.
The import path for SCSS/LESS/CSS/Stylus is simply:
@use '~@vp/swan/tokens';
After running codemods, if a ~
is newly added and you are facing build issues importing from ~@vp/swan/tokens
, try updating the import to remove the tilde: @vp/swan/tokens
.
Javascript is slightly different, and as imported from the main path:
import { tokens, tokensRaw } from '@vp/swan'
Figma
We also moved our SWAN UI Kit from styles to variables, which offer better support for modes, breakpoints, etc. For more information, see Designers.
Tiers
New tokens have three tiers noted in the token itself, each tier refers to the tier above it:
- Base - base tokens are an abstraction over raw values. They represent the scale and options for other tokens to pull from.
- Semantic - semantic tokens represent shared design decisions.
- Component - component tokens represent outlier decisions for necessary components. Not for public consumption.
The goal is to use the most semantic token possible. Thus, users should always aim to use a semantic token, using only a base token when necessary.
For more information, see Tokens.
Modes
For more consistency with how our modes are named, lightMode
has been replaced with standardMode
. compactMode
is a new mode to support denser UI for workspace-like views. For more information, see Modes.
Component tokens
We took a conscious approach to moving away from component tokens in SWAN 3.0. Before, they were often used as an escape hatch for inconsistency, and were used for snowflakes or custom components in an undesirable way. We’ve made SWAN a bit more internally consistent, and semantic tokens should take their place.
Props
Various React props reference our tokens through an abstraction. In v3.0 these have also changed to allow for more semantics, and to reflect the removal of their underlying tokens.
If you are upgrading SWAN prior to v3.0, note the warnings above tables to ensure you're migrating props at the correct time. In an effort to not create inconsistency, some props point to old tokens until v3.0 where they will be consolidated.
Migration tables can be found at the bottom of this document. For the rainbow palette and other marketing colors, see: Removing our old brand and marketing colors.
Objects
We’re removing the JS-only objects as these tokens often were out-of-date and represented unwanted solutions. Instead, users should use the equivalent JS token, which holds the same information and more appropriately reacts to modes.
The exception to these removals is MARKETING_COLORS
which has been move to @vp/marketing-colors
library.
Migrating old tokens
The All Tokens page has a list of all new tokens.
We also have a spreadsheet of the list of replacements for existing tokens. The tokens listed in the spreadsheet are language-agnostic, and must be prefixed with 'swan' appropriately. For example, base.color.transparent
is equivalent to $swan-base-color-transparent
in SASS, and SwanBaseColorTransparent
in JS. The 'difference' column notes the breadth of the change, with some tokens intentionally not having a replacement (usually marked as 'breaking').
Codemods exist to automate both the token changes and prop changes mentioned above. Many have already been released, with a few more set to be released with SWAN 3.0. These codemods will handle the bulk of the migration, but as always, we advise caution and QA, and note that the codemods can't cover everything.
Unfortunately, we can’t automate a migration to some semantic tokens, since they require knowledge of the intent of each use case. We encourage you to inspect you token usage and ensure you are using the most semantic token applicable. The more semantic usage, the stronger and more accurately new visual updates will propagate through Vista.
Note that, when possible, tokens now point to CSS Custom Properties. This means that you can no longer rely on literal values and perform interpolation or similar on tokens.
FAQs
I ran the codemods but some tokens didn't get replaced, what do I do?
Fix: Make sure that the latest version of the CLI is being used (npx @vp/swan-cli@latest).
When listing a long list of codemods and the list is too long, you may need to use the arrow keys to scroll up the list. If possible, an alternative to make the list shorter is use a --from value that is closer to the version being upgraded from. So instead of a blanket v2.0.0 → v3.0.0 update, you may update from v2.17.0.
I ran the latest codemods but some tokens still didn't get replaced, what do I do?
If some tokens fail to be replaced by a codemod, check out this spreadsheet for appropriate token replacements. The sheet is language agnostic to account for all formats, so you won’t be able to search for an exact string. For example: $swan-color-white-900 in SCSS would be color.white.900 in the spreadsheet.
Font size -1 and -2 aren’t replaced correctly
fontSize={-1} is being replaced with fontSize={-small}
This was an unexpected use case and has been fixed.
Fix: Upgrade swan-cli to >= v1.3.1
Font size incorrectly updated with undefined variable
fontSize={1} is being replaced with fontSize={xsmall} instead of fontSize={"xsmall"}
Fix: Update swan-cli to >= v1.3.0
Font sizes are completely wrong
Triage: The new typography scale wasn’t released until v2.22.0 so you must be on at least that version for the new scale to display correctly.
The work required to add the ability to replace “global” variables in SCSS was getting very complicated. As of SWAN-CLI v1.4.0, this is not supported but we are looking into possible options.
Fix: Support added in v1.5.0. Make sure that the latest version of the CLI is being used (npx @vp/swan-cli@latest).
The tokens import path is being updated to add a tilde (~) during migration. Depending on your build tooling, this may cause issues even if the import is correct.
Fix: Support added in v1.6.0. Make sure that the latest version of the CLI is being used (npx @vp/swan-cli@latest).
Why do some colors look different?
Some colors have changed intentionally, and others have been removed. Teams should VQA with their designer, and reach out if they have any questions.
Font sizes are larger from the upgrade
The new typography scale is not a 1:1 replacement, as we have consolidated many different APIs and values for font sizes. Teams should VQA with their designer and adjust as necessary using the new scale.
Token-related prop replacements
backgroundColor
For the rainbow palette and other marketing colors, see: Removing our old brand and marketing colors, and review the table below.
OLD PROP | REPLACEMENT |
__ | standard |
__ | strong |
__ | accent |
__ | error |
__ | help |
__ | promo |
__ | success |
__ | warning |
discount | promo |
grey-200 / gray-200 | strong |
grey-100 / gray-100 | strong |
platinum | strong |
light-grey / light-gray | strong |
white-900 | standard |
black-900 | black (consider if standard + darkMode is better) |
dark-blue | accent |
atlantic | accent |
kingfisher | accent |
loading-shimmer | loadingShimmer (core prop) |
grey-900, grey-800, grey-700, grey-600, grey-500, grey-400, grey-300 | __ |
gray-900, gray-800, gray-700, gray-600, gray-500, gray-400, gray-300 | __ |
green-700 | success / promo (if semantically correct) |
green-100 | success / promo (if semantically correct) |
yellow-700 | warning (if semantically correct) |
emerald-700 | success / promo (if semantically correct) |
emerald-100 | success / promo (if semantically correct) |
graphite | __ |
dark-grey / dark-gray | __ |
medium-grey / medium-gray | __ |
light-blue | __ |
medium-green | success / promo (if semantically correct) |
medium-yellow | warning (if semantically correct) |
caspian | __ |
celtic | __ |
iris | __ |
mandarin | __ |
opal | __ |
pumpkin | __ |
rio | __ |
rum | __ |
santorini | __ |
scarlet | __ |
talavera | __ |
ultramarine | __ |
violet | __ |
textColor
OLD PROP | REPLACEMENT |
__ | standard |
__ | subtle |
__ | error |
__ | warning |
__ | success |
__ | promo |
__ | help |
__ | accent |
alert | error |
white | standard + darkMode |
black | standard |
black-800 | standard |
dark-grey / dark-gray | subtle |
grey-700 / gray-700 | subtle |
fontSize
textSize | fontSize (Legacy) | fontSize ("x" scale) | fontSize (current) |
1 | 6 | x6, x5, x4 | x4large |
2 | 5 | x3 | x3large |
3 | 4 | x2 | x2large |
4 | 3 | x1 | large |
5 | 2 | x, x0 | standard |
6 | 1 | xm1 | small |
7 | m1, m2, -1, -2 | xm2 | xsmall |
fontFamily
OLD PROP | REPLACEMENT |
primary | primary |
secondary | primary |
special | secondary |
fontWeight
OLD PROP | REPLACEMENT |
normal | normal |
bold | bold |
bolder | bold |
fontSkin
fontSkin
contains 5 styling decisions (fontSize
, fontFamily
, fontWeight
, lineHeight
, letterSpacing
). It's an extra migration to get ensure you're using the most semantic token. When moving to fontSkin
, you should remove all other styling.
fontFamily
is replaced by Output font
in the below table, due to the props changing between v2.22 and v3.0.
Ensure the resulting fontSkin
used matches the semantics and design intent of the page.
Complete this migration only after completing the fontSize
, fontFamily
, and fontWeight
migrations.
fontSize | Output font | fontWeight | Replacement (fontSkin) |
x4large | Graphik, Tiempos | normal, bold | title-display |
x3large | Graphik | normal, bold | title-headline |
x3large | Tiempos | normal, bold | editorial-headline |
x2large | Graphik, Tiempos | normal, bold | title-section |
xlarge | Graphik, Tiempos | normal, bold | editorial-content |
large | Tiempos | normal, bold | editorial-content |
large | Graphik | normal, bold | title-subsection |
standard | Graphik, Tiempos | bold | title-item |
standard | Graphik, Tiempos | normal | body-standard |
standard | Graphik, Tiempos | bold | body-standard-bold |
small | Graphik, Tiempos | normal | body-small |
small | Graphik, Tiempos | bold | body-small-bold |
xsmall | Graphik, Tiempos | normal | footnote |
xsmall | Graphik, Tiempos | bold | footnote-bold |
space (margin, padding, etc)
Be sure to only migrate these values once, either through codemods or manually - not both!
Old props | Replacement |
0 | 0 |
1 | 2 |
2 | 3 |
3 | 4 |
4 | 5 |
5 | 6 |
6 | 7 |
7 | 7 |
8 | 8 |
9 | 9 |
10 | 10 |
11 | 11 |
12 | 12 |
13 | 12 |
Miscellaneous
Typescript Types
- The
StyleSpacing0to13
type should be replaced withStyleSpaceWithAuto
- The
ScreenClasses
type should be replaced withStyleBreakpoints
SCREEN_CLASS_MIN_WIDTHS, SCREEN_CLASS_MAX_WIDTHS
The deprecated Screen Class objects should be replaced with tokens. import { tokensRaw } from '@vp/swan'
Old Expression | New Expression |
SCREEN_CLASS_MIN_WIDTHS.xs | tokensRaw.SwanBaseBreakpointXsStart |
SCREEN_CLASS_MIN_WIDTHS.sm | tokensRaw.SwanBaseBreakpointSmStart |
SCREEN_CLASS_MIN_WIDTHS.md | tokensRaw.SwanBaseBreakpointMdStart |
SCREEN_CLASS_MIN_WIDTHS.lg | tokensRaw.SwanBaseBreakpointLgStart |
SCREEN_CLASS_MIN_WIDTHS.xl | tokensRaw.SwanBaseBreakpointXlStart |
SCREEN_CLASS_MAX_WIDTHS.xs | tokensRaw.SwanBaseBreakpointXsEnd |
SCREEN_CLASS_MAX_WIDTHS.sm | tokensRaw.SwanBaseBreakpointSmEnd |
SCREEN_CLASS_MAX_WIDTHS.md | tokensRaw.SwanBaseBreakpointMdEnd |
SCREEN_CLASS_MAX_WIDTHS.lg | tokensRaw.SwanBaseBreakpointLgEnd |
SCREEN_CLASS_MAX_WIDTHS.xl | tokensRaw.SwanBaseBreakpointXlEnd |
Overview
SWAN v2 is a major version release focused on React 18 support. React 18 provides a number of new features, and is mandatory for the latest major release of some frameworks like Gatsby and Next.js.
- Some of the components that SWAN provides in v1 (Combobox, Listbox, ModalDialog, Popover) depended on the reach-ui library, which is no longer maintained and doesn't provide full support for React 18. We have now shifted our dependency to react-aria, a headless UI library, which doesn't implement any rendering or impose DOM structure, but provides behavior, accessibility, and interactions, letting us focus on our design.
- SWAN v2 also updates the paths to tokens, to provide better multi-platform support.
- There are some other updates as well with this release. Curious? Head over to the v2.0 changelog
.
We expect a smooth upgrade for most users, as only a couple of changes will be required: running a codemod, and a handful of manual code changes.
Do you think that something is not covered here? Refer to the FAQs section or contact us on #help-swan
Breaking Changes
Automated
We automated as many of the breaking changes as possible. See the Codemods tab for instructions for running the codemod script. The script will:
- change the modified components to use the new "Legacy___" names
- update the paths for tokens
- update the two design tokens for the Range component whose names were normalized
Manual
While we tried to cover all the SWAN v2 updates with the codemod, the script couldn't handle everything. Here are the things that need to be manually updated:
1. Server-side rendering: wrapping with SwanSSRProvider
If you are server-side rendering and using React 17, you will now need to wrap your application in a <SwanSSRProvider>
to avoid hydration issues. Place it as a child of <SwanProvider>
in the SwanConfiguration component (if you have created one, referenced in our setup docs). If you're on React 18, this is not necessary.
2. Renamed components: React 18 support
As mentioned in the introduction, our components Combobox
, Listbox, ModalDialog
, and Popover
were dependent on a library in SWAN 1 that was not fully compatible with React 18. These components were rewritten in SWAN v2 using a new library, so their implementation and APIs changed.
To ease the transition, we have kept the old components available for your use in SWAN v2. These legacy implementations are now prefixed with the keyword "Legacy
". For example, the new, rewritten Modal Dialog that is compatible with React 18 is ModalDialog
, and the older version has been renamed to LegacyModalDialog
.
The codemod script above will migrate your code to the legacy versions of these components. If you want to leverage React 18, you will need to manually upgrade the above-mentioned components to their new implementations.
3. ModalDialog
The new ModalDialog component uses the native dialog
element, which behaves differently than the legacy modal dialog component.
Unit Testing in Jest
jsdom, the node-based implementation of browser standards that jest uses to render react inside of unit tests, does not support the HTMLDialogElement API. This might cause unit tests to fail with an error like "dialogRef.current.showModal is not a function." Add the following to your jest setup file:
Note: Since JSDOM doesn't implement the HTMLDialogElement
API, the onRequestDismiss
callback won't be triggered when the dialog's close event occurs.
Rendering
By default, the contents inside of the dialog will be rendered in the DOM, but not visible until the dialog is open. This behavior does not match that of the legacy modal dialog, where contents were only rendered when the modal was opened. Any code that runs on the mount (like a useEffect) will run when the Modal is first rendered on the page, not when it is opened. We have added a new prop, onlyRenderWhenOpen
, to the new ModalDialog to mimic the legacy behavior.
4. LESS and Stylus users: Tokens path update
SWAN v2 updated the paths to our tokens. So, if previously you were importing any token from the path @vp/swan/tokens/tokens
, it's been updated to @vp/swan/design-tokens/[type]
, where type ∈ {scss, css, less, stylus}.
For the types scss
and css
, our codemod script will update the paths for you. But if you are using LESS or Stylus tokens, you'll need to update your import paths manually.
5. NextJs 12 updates
We employ @react-aria
package for rendering a few of our components(Listbox, Combobox, Popover). The before-mentioned package has a known issue with NextJs 12. To solve this, either you can upgrade to NextJs 13, which would be additional work considering SWAN migration, but good to have in the long run; or you can add the overrides in your package.json as below to get an immediate resolution:
It would be nice to have a comment regarding this as in the example above, because this would be needed only if you are using NextJs 12 and should be removed if upgrading to NextJs 13.
Future breaking changes
- SWAN v3 will remove all the legacy and deprecated components and properties in SWAN v2. We have marked each deprecated component using the
@deprecated
jsdoc tag, which you IDE will display in code with a strikethrough. This is going to be a general trend for each major release; the previous version's legacy functionality will be removed.
FAQs
No, SWAN v2 is compatible with both React 17 and React 18. However, upgrading to React 18 will be required as part of the JavaScript RFC work.
When you do switch to React 18, make sure you replace your usage of the Legacy components mentioned above, as they have no guarantee of working with React 18 features like concurrency.
If your library uses none of the breaking changes, you may be able to support both v1 and v2 simultaneously.
However, semantically, each library owner should release a new major version that uses SWAN version 2 to avoid issues with backward compatibility.
Library authors will be required to upgrade by the end of October 2023 (as part of Vista's overall move to React 18), and the page owners by January 2024. Please work with your PM to add this to your roadmaps.
How would you rate the SWAN documentation?