Migration Guide
- Migrate to v2.85.0
- Migrate to v2.74.0
- Migrate to v2.64.0
- Migrate to v2.55.0
- Migrate to v2.49.0
- Migrate to v2.44.0
- Migrate to v2.43.0
- Migrate to v2.40.0
- Migrate to v2.24.0
- Migrate to v2.19.0
- Migrate to v2.17.0
- Migrate to v2.12.0
- Migrate to v2.11.0
- Migrate to v2.9.0
- Migrate to v2.0.0-beta.48
- Migrate to v2.0.0-beta.37
- Migrate to v2.0.0-beta.31
- Migrate to v2.0.0-beta-29
- Migrate to v2.0.0-beta.25
- Migrate to v2.0.0-color.9
- Migrate to v2.0.0-beta.17
- Migrate to v2.0.0-beta.15
- Migrate to v2.0.0-beta.12
- Migrate to v2.0.0-beta.8
- Migrate to v2.0.0-beta.6
- Migrate to v2.0.0-beta.4
- Migrate to v2.0.0-beta.0
- Migrate to v1.0.0-beta.2
- Migrate to v1.0.0-beta.0
Migrate to v2.85.0
Separator compact
DEPRECATED Separator’s compact
prop, displaying a Separator in its compact form will become the default in an upcoming major GDS version. To future-proof things, i.e. to avoid having no spacing before and after the separator line, the newly added spacing
prop can and should already be set on all Separators that have no compact prop.
There are two possible values for the spacing
prop. First and foremost, REGULAR
will add a 6px
margin before and after the Separator. However, when Separator is used to create a divider line inside a Card or Modal, we want to INHERIT
the spacing from whatever is set on the Card or Modal. Doing results in 10px
in a Card with medium padding, 32px
in Card with large padding, and 16px
inside a Modal.
So the migration strategy depends on where and how Separator is used. Given that the aforementioned Card/Modal divider line is an ability that has only been added recently, it is safe to assume that REGULAR
spacing will be needed in almost all cases. A notable exception is the protrude
prop that has also been added only recently: When protrude
is set and compact
isn’t, a Separator’s spacing should most definitely be INHERIT
.
jsx// old: compact not set (or set to false)
<Separator />
// new (most cases): 6px spacing
<Separator spacing={Separator.SPACING.REGULAR} />
// new (exception): 10px/32px/16px spacing
<Separator spacing={Separator.SPACING.INHERIT} />
Contrary, wherever compact
is set, there is no need to future-proof things, but at the same time no change is possible, so for now the prop needs to be kept.
jsx// old: compact is true
<Separator compact />
// new: same as before, DO NOT CHANGE
<Separator compact />
Migrate to v2.74.0
DropdownToggle with old Button
Using old Button in DropdownToggle has been deprecated. This has several aspects.
useNewButton
prop should be set totrue
for now, until it is removed altogether.color
prop should not be used anymore. Usevariant
instead.size
prop should no longer be set toSIZE.LARGE
. The NewButton supportsSMALL
andMEDIUM
sizes and so will the DropdownToggle.
jsx// old
<DropdownToggle
color={DropdownToggle.COLOR.PRIMARY}
size={DropdownToggle.SIZE.LARGE}
>
…
</DropdownToggle>
// new
<DropdownToggle
variant={DropdownToggle.VARIANT.PRIMARY}
size={DropdownToggle.SIZE.MEDIUM}
useNewButton
>
…
</DropdownToggle>
ClearableButton with old Button
Using old Button in ClearableButton has been deprecated. This means:
useNewButton
prop should be set totrue
for now, until it is removed altogether.size
prop should no longer be set toSIZE.LARGE
. The NewButton supportsSMALL
andMEDIUM
sizes and so will the ClearableButton.
jsx// old
<ClearableButton
size={ClearableButton.SIZE.LARGE}
…
>
…
</ClearableButton>
// new
<ClearableButton
size={ClearableButton.SIZE.MEDIUM}
useNewButton
…
>
…
</ClearableButton>
Migrate to v2.64.0
SnackbarItem message
SnackbarItem’s message
prop being optional has been DEPRECATED, it will become mandatory in an upcoming major GDS version.
Currently, the text to be announced in screen readers is retrieved by parsing SnackbarItem’s children
, which may lead to undesirable results. To ensure proper spoken text, said text must be provided:
jsx// old
<SnackbarItem variant={…}>
Text and more.
</SnackbarItem>
// new
<SnackbarItem variant={…} message="Text">
Text and more.
</SnackbarItem>
Migrate to v2.55.0
Table Wrapper
A Table’s ability to provide its own wrapper – which adds a thin border line around the table when placed inside a padded Card – has been DEPRECATED.
The ability will be removed in an upcoming major GDS version, Tables that require a border line around them need to be wrapped inside an unpadded Card. In other words, a nested Card wraps the Table inside the already present Card:
jsx// old
<Card>
...
<Table>...table content...</Table>
...
</Card>
// new
<Card>
...
<Card padded={false}>
<Table>...table content...</Table>
</Card>
...
</Card>
See Playroom example for more details.
Migrate to v2.49.0
InfoCardHeader with ContactInfo
While ContactInfo inside a CardHeader with variant
INFO
sees continued support, for most purposes it is beneficial to switch to ProductInfo instead, because ProductInfo is more versatile and lets you set all the information – that previously had to be split up into individual paragraphs – directly. Both the old and the improved version shown below produce the same result visually.
jsx// old
<CardHeader variant={CardHeader.VARIANT.INFO} alignment={…}>
<Paragraph>
<ContactInfo
avatar={<Avatar icon={…} color={…} />}
alias="Transaction title"
/>
</Paragraph>
<Paragraph>
<Inline small>Transaction subtitle (Optional)</Inline>
</Paragraph>
<Paragraph>
<Amount value="12345" currency={…} />
</Paragraph>
</CardHeader>
// improved
<CardHeader variant={CardHeader.VARIANT.INFO} alignment={…}>
<Paragraph>
<ProductInfo
avatar={<Avatar icon={…} color={…} />}
alias="Transaction title"
productNumber="Transaction subtitle (Optional)"
amount={<Amount value="12345" currency={…} />}
/>
</Paragraph>
</CardHeader>
In order to know whether to migrate or not, you should ask yourself if the CardHeader resembles “a contact” or “a product”, and choose ContactInfo/ProductInfo accordingly. Or simply migrate all cases that result in fewer paragraphs.
HINT Depending on your use case, it may be required to set the ProductInfo’s verbosity
level to REGULAR
; in this case you have to provide all the labels (aliasLabel
, productNumberLabel
, etc.) for each line of visible text too.
Migrate to v2.44.0
Horizontal-/VerticalFunctionCard
DEPRECATED VerticalFunctionCard, use FunctionCard instead
The new FunctionCard component without horizontal
prop must be used as a VerticalFunctionCard replacement. However, the way “body” content gets sent in may need an update.
If VerticalFunctionCard either used buttonsText
and no children
, or both buttonsText
and children
, the new FunctionCard component can be used as a 1 to 1 replacement. If on the other hand VerticalFunctionCard solely used children
, content now needs to be sent via buttonsText
. The latter is also true for Function Information Cards, which happen to be vertical FunctionCards with some heading style tweaks, and no indicator.
jsx// --- children only, now via buttonsText ---
// old:
<VerticalFunctionCard {...props}>{children}</VerticalFunctionCard>
// new:
<FunctionCard {...props} buttonText={children} />
// --- and the two easy other cases for comparison ---
// old:
<VerticalFunctionCard {...props} buttonText={buttonsText} />
// new:
<FunctionCard {...props} buttonText={buttonsText} />
// old:
<VerticalFunctionCard {...props} buttonText={buttonsText}>{children}</VerticalFunctionCard>
// new:
<FunctionCard {...props} buttonText={buttonsText}>{children}</FunctionCard>
DEPRECATED HorizontalFunctionCard, use FunctionCard with horizontal
instead
The new FunctionCard component with horizontal
prop is a 1 to 1 replacement for HorizontalFunctionCard.
jsx// old:
<HorizontalFunctionCard {...props}>{children}</HorizontalFunctionCard>
// new:
<FunctionCard {...props} horizontal>{children}</FunctionCard>
DEPRECATED HorizontalFunctionCardGroup, use CardGroup or Group instead
The new horizontal FunctionCard no longer needs a dedicated HorizontalFunctionCardGroup wrapper, it can be placed in a regular CardGroup. In the unlikely event you have a standalone horizontal FunctionCard (i.e. without any siblings) on grey background, you can even put it in a plain Group.
jsx// --- any content that actually needs "grouping", i.e. at least 2 cards ---
// old:
<HorizontalFunctionCardGroup>
<HorizontalFunctionCard {...props}>{children}</HorizontalFunctionCard>
<HorizontalFunctionCard {...props}>{children}</HorizontalFunctionCard>
</HorizontalFunctionCardGroup>
// new:
<CardGroup>
<FunctionCard {...props} horizontal>{children}</FunctionCard>
<FunctionCard {...props} horizontal>{children}</FunctionCard>
</CardGroup>
// --- single/standalone horizontal FunctionCard ---
// old:
<HorizontalFunctionCardGroup>
<HorizontalFunctionCard {...props}>{children}</HorizontalFunctionCard>
</HorizontalFunctionCardGroup>
// new:
<Group>
<FunctionCard {...props} horizontal>{children}</FunctionCard>
</Group>
Migrate to v2.43.0
ProductCard size
BREAKING removed ProductCard size
, please use variant
instead.
Former size value | New variant value |
---|---|
SMALL (default) | PLUGIN (default) |
MEDIUM | TEASER |
LARGE | LARGE_TEASER |
Migrate to v2.40.0
ActivatedPluginCard
DEPRECATED ActivatedPluginCard, please use ProductCard instead.
Can be used as a 1 to 1 replacement, with two key differences:
- ActivatedPluginCard’s
color
prop must be mapped to ProductCard’scolorValue
prop, and not thecolor
prop (which also exists). - ActivatedPluginCard’s
buttonsText
prop must be mapped to ProductCard’sprice
prop, and you are only allowed to send inline content, a wrapper paragraph is created automatically.
Stripe pluginColor
BREAKING Removed pluginColor
prop, use colorValue
instead
jsx// old:
<StripeHeader
pluginColor="#eeeeee"
…
/>
// new:
<StripeHeader
colorValue="#eeeeee"
…
/>
Migrate to v2.24.0
Dual currency OverviewCard
BREAKING Removed extraAmountsConverted
prop, use extraAmounts
with structured objects
jsx// old:
<OverviewCard
mainAmount={<OverviewCardAmount … />}
mainAmountConverted={<OverviewCardAmount … />}
extraAmounts={[<OverviewCardAmount … />]}
extraAmountsConverted={[<OverviewCardAmount … />]}
…
/>
// new:
<OverviewCard
mainAmount={<OverviewCardAmount … />}
mainAmountConverted={<OverviewCardAmount … />}
extraAmounts={[
{
original: <OverviewCardAmount … />,
converted: <OverviewCardAmount … />,
}
]}
…
/>
Migrate to v2.19.0
Button unstyled .g-button-avatar
DEPRECATED the need to set unstyled
and .g-button-avatar
when Button contains an Avatar in its children
, those props may now be omitted.
jsx// old:
<Button unstyled className="g-button-avatar" icon={Button.ICON.CAMERA} aria-label="Button Label">
<Avatar icon={Avatar.ICON.USER} />
</Button>
// new:
<Button icon={Button.ICON.CAMERA} aria-label="Button Label">
<Avatar icon={Avatar.ICON.USER} />
</Button>
Migrate to v2.17.0
Transaction date without Moment.js
DEPRECATED usage of Moment.js in Transaction.date
. Unfortunately, this also means, that all format strings will have to be updated, as date-fns uses Unicode Tokens, which is the accepted new standard for date formatting tokens.
jsx// old:
<Transaction
date={moment('2022-03-24')}
dateFormat="DD.MM.YYYY"
largeDateFormat="D MMM [escaped]"
largeDateFormatYear="YYYY"
/>
// new:
<Transaction
date={new Date('2022-03-24')}
dateFormat="dd.MM.yyyy"
largeDateFormat="d MMM 'escaped'"
largeDateFormatYear="yyyy"
/>
Please note, that should you decide to migrate to use JavaScript Dates instead of Moment.js, that globally defined formats in LanguageProvider will have to be migrated as well. Here’s a list of the affected keys:
format.date
format.isoDate
format.screenreaderDate
transaction.format.date
transaction.format.largeDate
transaction.format.largeDateYear
Migrate to v2.12.0
TransactionMenu
With the introduction of TransactionMenu, support for an overlay with buttons as used in Order list transactions has been deprecated. TransactionMenu uses MenuDropdown internally and will forward all props to it.
jsx// old:
<TransactionGroup columns={{ overlay: { show: true } }}>
<Transaction
title="Shows an overlay on hover"
overlay={
<ButtonGroup buttonSize={ButtonGroup.BUTTON_SIZE.SMALL}>
<Button variant={Button.VARIANT.SECONDARY} onClick={() => {}}>Sign</Button>
<Button variant={Button.VARIANT.SECONDARY}>Edit</Button>
<Button variant={Button.VARIANT.SECONDARY}>Delete</Button>
</ButtonGroup>
}
/>
</TransactionGroup>
// new:
<TransactionGroup columns={{ menu: { show: true } }}>
<Transaction
title="Shows a menu with actions"
menu={
<TransactionMenu
{...DropdownMenuProps}
toggleLabel="Actions"
items={[
{ value: 'sign', label: 'Sign', onClick: () => {} },
{ value: 'edit', label: 'Edit' },
{ value: 'delete', label: 'Delete' },
]}
/>
}
/>
</TransactionGroup>
PrimaryNavigationDropdownToggle
BREAKING PrimaryNavigationDropdownToggle has been removed, as PrimaryNavigationButton now comes with a showDropdownIndicator
, which makes the toggle obsolete.
PrimaryNavigationDropdownToggle made sure that the icon of a navigation item is always the downward-facing caret. With this release, the dropdown indicator is a separate thing, which means icon and a dropdown indicator at the same time become possible. Essentially, we now support all combinations of navigation item content (icon, label, pill, dropdown indicator).
Consequently, this change enables us to add a dropdown indicator to icon-only buttons, but for now we continue the old way for aesthetic reasons. Therefore, this is no 1:1 migration, i.e. not all occurances of PrimaryNavigationDropdownToggle will be turned into PrimaryNavigationButton with showDropdownIndicator={true}
.
Navigation items that have a visible label should be migrated like this:
jsx// old:
<PrimaryNavigationDropdownToggle>
Your Products
</PrimaryNavigationDropdownToggle>
// new:
<PrimaryNavigationButton showDropdownIndicator>
Your Products
</PrimaryNavigationButton>
In contrast, for items that only show the icon, use PrimaryNavigationButton without showDropdownIndicator
:
jsx// old:
<PrimaryNavigationDropdownToggle
hiddenLabel={PrimaryNavigationButton.HIDDEN_LABEL.ALWAYS}
icon={PrimaryNavigationButton.ICON.COMMENT}
>
Your Messages
</PrimaryNavigationDropdownToggle>
// new:
<PrimaryNavigationButton
hiddenLabel={PrimaryNavigationButton.HIDDEN_LABEL.ALWAYS}
icon={PrimaryNavigationButton.ICON.COMMENT}
>
Your Messages
</PrimaryNavigationButton>
Needless to say, navigation items that are already using PrimaryNavigationButton – i.e. those that do not open a dropdown – need no migration, as showDropdownIndicator
defaults to false.
Bottom line, PrimaryNavigationDropdownToggle usually resides in Dropdown’s renderToggle
, migrate all occurances to PrimaryNavigationButton with/without dropdown indicator.
jsx// new - with PrimaryNavigationDropdownToggle already replaced:
<Dropdown
renderToggle={() => (
<PrimaryNavigationButton showDropdownIndicator={!isIconOnlyButton}>
Your Products
</PrimaryNavigationButton>
)}
>
{/* dropdown content */}
</Dropdown>
Migrate to v2.11.0
Avatar hoverIcon
DEPRECATED all hoverIcon*
props, hence the scenarios shown in the example code marked as “old” should be migrated to the new format, where the Avatar is wrapped in an unstyled Button with an icon and the modifier .g-button-avatar
applied. The Button’s icon
replaces Avatar’s hoverIcon
, and no tabIndex
should be needed anymore.
jsx// old - without button, but something (e.g. a Dropdown) that had a tabIndex:
<Dropdown
tabIndex={0}
renderToggle={<Avatar icon={Avatar.ICON.USER} hoverIcon={Button.ICON.CAMERA} />}
>
{children}
</Dropdown>
// old - without button, the Avatar itself had a tabIndex:
<Avatar icon={Avatar.ICON.USER} hoverIcon={Button.ICON.CAMERA} tabIndex={0} />
// old - already with unstyled button, but only a `.g-button-rounded` modifier class:
<Button unstyled className="g-button-rounded" aria-label="Button Label">
<Avatar icon={Avatar.ICON.USER} hoverIcon={Button.ICON.CAMERA} />
</Button>
// new:
<Button unstyled className="g-button-avatar" icon={Button.ICON.CAMERA} aria-label="Button Label">
<Avatar icon={Avatar.ICON.USER} />
</Button>
Amount in ProductSelect/RecipientSelect
DEPRECATED amount data in the items’ product data in ProductSelect and RecipientSelect in favour of an actual Amount element:
jsx// old:
<ProductSelect
items={[
...items,
{
label: 'Product',
value: 'product',
product: {
...productData,
amount: {
value: '123456',
currency: 'EUR',
color: Amount.COLOR.POSITIVE,
}
}
}
]}
/>
// new:
<ProductSelect
items={[
...items,
{
label: 'Product',
value: 'product',
product: {
...productData,
amount: <Amount value="123456" currency="EUR" color={Amount.COLOR.POSITIVE} />
}
}
]}
/>
Migrate to v2.9.0
While Transaction components are still in BETA status, the changes this time are quite significant, so we tried to deprecate as much as possible. Here’s a quick overview of what has changed:
- visual update in list and detail (date column, indicators under amounts, improved padding, alignment of Retail, Pro and Business)
- one customisable Transaction component instead of two variants
- alignment of prop, column and language key names
- full control over visibility of all columns in TransactionGroup and TransactionDetail
- direct usage of Avatar instead of
icon
andimageUrl
- new dedicated
alert
column
Transaction
To streamline the usage of Transaction/TransactionDetail and enable various different configurations, the special variants AccountTransaction and OrderTransaction got deprecated in favour of a single Transaction component. Please refer to the following table to see how the props translate. The props of TransactionDetail are similarly affected by this change.
DEPRECATED prop | New prop |
---|---|
*Transaction.icon | Transaction.avatar |
*Transaction.imageUrl | Transaction.avatar |
*Transaction.renderType | Transaction.renderAvatar |
*Transaction.bigDateFormatUpper | Transaction.largeDateFormat |
*Transaction.bigDateFormatLower | Transaction.largeDateFormat |
*Transaction.bigDateFormatYear | Transaction.largeDateFormatYear |
AcountTransaction.description | Transaction.info |
AcountTransaction.note | Transaction.info |
AcountTransaction.categories | Transaction.badges |
OrderTransaction.statuses | Transaction.badges |
jsx// old:
<AccountTransaction
description="Description"
note="Note"
categories={["Improvements & furniture", "Home"]}
icon={AccountTransaction.ICON.BUILDING_SAVINGS}
bigDateFormatUpper="D"
bigDateFormatLower="MMM"
bigDateFormatYear="YYYY"
renderType={({ children, icon, imageUrl }) => children }
/>
<OrderTransaction
statuses={["Open"]}
imageUrl="path-to-asset"
/>
// new:
<Transaction
info="Description or Note"
badges={[
<Badge key="1" variant={BADGE.VARIANT.CATEGORY} text="Improvements & furniture" />
<Badge key="2" variant={BADGE.VARIANT.CATEGORY} text="Home" />
]}
avatar={<Avatar icon={Avatar.ICON.BUILDING_SAVINGS} />}
largeDateFormat="D MMM"
largeDateFormatYear="YYYY"
renderAvatar={({ children, avatar }) => children }
/>
<Transaction
info="Description or Note"
badges={[
<Badge key="1" variant={BADGE.VARIANT.TODO} text="Open" />
]}
avatar={<Avatar imageUrl="path-to-asset" />}
/>
TransactionGroup
To further align the APIs of Transaction components, column names and language string keys have been aligned with their respective prop in Transaction:
Old TransactionGroup | New TransactionGroup | BREAKING New LanguageProvider key |
---|---|---|
columns.type | columns.avatar | transaction.header.avatar |
columns.description | columns.info | transaction.header.info |
columns.actions | columns.overlay | transaction.header.overlay |
columns.details | columns.detail | transaction.header.detail |
Furthermore, it is now possible to control all individual columns through a show
property in the respective column. Similar to that, showInDetail
can be used to control visibility of individual columnns inside the TransactionDetail.
By default, TransactionGroup uses the following default configuration:
jsxconst COLUMN_DEFAULTS = {
selectable: { show: false, showInDetail: false },
date: { show: true, showInDetail: true },
avatar: { show: true, showInDetail: true },
title: { show: true, showInDetail: true },
amount: { show: true, showInDetail: true },
indicators: { show: true, showInDetail: true },
info: { show: true, showInDetail: true },
misc: { show: false, showInDetail: false },
badges: { show: true, showInDetail: false },
alert: { show: false, showInDetail: false },
overlay: { show: false, showInDetail: false },
detail: { show: true, showInDetail: false },
};
To further illustrate the changes mentioned above, here’s a stripped down example a TransactionGroup component:
jsx// old:
<TransactionGroup
selectable
showDate={false}
showType={false}
columns={{
selectable: { label: 'Select transaction' },
date: { label: 'Date' },
type: { label: 'Type' },
description: { label: 'Description' },
actions: { label: 'Actions' },
details: { label: 'Transaction details' },
}}
>
... Transactions
</TransactionGroup>
// new:
<TransactionGroup
columns={{
selectable: { show: true, label: 'Select transaction' },
date: { show: false, label: 'Date' },
avatar: { show: false, label: 'Type' },
info: { label: 'Description' },
detail: { label: 'Transaction detail' },
}}
>
... Transactions
</TransactionGroup>
Migrate to v2.0.0-beta.48
TransactionGroup columns
With the added support of sortable
Transactions through TransactionGroup we’ve added the ability to customize the columns
of the underlying table, this also includes their label
, so the abstraction of those labels into dateLabel
and the like are no longer necessary. Labels provided through LanguageProvider strings are unaffected by this change.
jsx// old:
<TransactionGroup
dateLabel="Date"
badgesLabel="Status"
>
... Transactions
</TransactionGroup>
// new:
<TransactionGroup
columns={{
date: { label: 'Date' },
badges: { label: 'Date' },
}}
>
... Transactions
</TransactionGroup>
Each label translates into its own column like follows:
DEPRECATED key | New key |
---|---|
dateLabel | columns.date.label |
typeLabel | columns.type.label |
titleLabel | columns.title.label |
amountLabel | columns.amount.label |
indicatorsLabel | columns.indicators.label |
badgesLabel | columns.badges.label |
descriptionLabel | columns.description.label |
miscLabel | columns.misc.label |
actionsLabel | columns.actions.label |
detailsLabel | columns.details.label |
selectableLabel | columns.selectable.label |
Migrate to v2.0.0-beta.37
CardHeader
- Update LargeCardHeader (see below).
- Update
<InfoCardHeader />
to<CardHeader variant={CardHeader.VARIANT.INFO} />
.
jsx// old:
<LargeCardHeader
left={left}
right={right}
>
Title
</LargeCardHeader>
// new:
<StripeHeader
left={left}
right={right}
center={
<StripeTitle>Title</StripeTitle>
}
/>
Meter
BREAKING The Meter
component has lost three abilities, and two things have changed:
- It no longer handles
min
>max
ranges. - It no longer has a
tooltip
property. - It no longer has a
description
property. - The misspelt
auxillaryValue
was changed toauxilaryValue
, but this is also misspelt, as it should beauxiliaryValue
, which is why is was changed toauxValue
. - The label now shows the uncapped value.
Removal of min
> max
support
With this change, min
≤ max
applies. Most likely there is no “countdown meter” out there, because the implementation had bugs. Instead of fixing them, this feature has been removed, as the range boundaries can easily be flipped (recalculated) before sending them to Meter.
Removal of tooltip
The tooltip
property is not needed, as Meter can simply be wrapped inside an actual Tooltip. This comes with the additional benefit of all Tooltip properties being usable.
jsx<Tooltip tag="div" content="You have saved 60% of the required amount.">
<Meter value={60} />
</Tooltip>
Removal of description
Setting the now removed description
property resulted in an aria-label
on the Meter, which does not work on <span>
elements in most screen readers. So do not replace it with aria-label
, instead augment it with VisuallyHidden text.
There are two scenarios where you do not need a description: 1. Meter is wrapped inside a self-explanatory Tooltip; and 2. Meter has enough text before/after it which covers the explanation. For everything else, supplementary text is needed to replace what previously went in description
, like shown below.
jsx// add a description that is announced instead of the Meter value
<Meter value={60} aria-hidden /><VisuallyHidden>You have saved 60% of the required amount.</VisuallyHidden>
// add a description to Meter without hiding it's value
<VisuallyHidden>You have saved </VisuallyHidden><Meter value={60} /><VisuallyHidden> of the required amount.</VisuallyHidden>
Fixed typo in auxiliary value
Change all auxillaryValue
to auxValue
.
Change in label behaviour
If you use Meter with a value
ouside the min
/max
range, the length of the bar is determined by the capped value, but the contained text is now holding the uncapped value.
jsx// As `max` defaults to 100, this will now show 110% instead of 100%
<Meter value={110} showLabel />
// 👉 output: <span class="g-meter…>110%</span>
// If you *really* need the old behaviour, use either
<Meter value={110} showLabel label="100%" />
// or alternatively recalculate and send in the capped value
<Meter value={100} showLabel />
// But! Most likely you wanted the uncapped value anyway, so now
// you can remove any `label="110%"` you had to add previously.
Migrate to v2.0.0-beta.31
New buttons
BREAKING The Button
component no longer has an iconLabel
for icon-only buttons, specifying a label now works identical for all kinds of buttons, i.e. label only, icon only, and label with icon. To hide the label, set hiddenLabel
to Button.HIDDEN_LABEL.ALWAYS
. (In most cases, you also want to set fullWidth
to Button.FULL_WIDTH.NEVER
at the same time.)
jsx// to get an icon-only (primary) button
<Button
icon={Button.ICON.DELETE}
fullWidth={Button.FULL_WIDTH.NEVER}
hiddenLabel={Button.HIDDEN_LABEL.ALWAYS}
>
Mandatory label
</Button>
Migrate to v2.0.0-beta-29
DropdownToggle useNewButton
logic
The DropdownToggle component now supports replacing its internal button for the new one:
jsx// old button accepts a `color` prop
<DropdownToggle
color={DropdownToggle.COLOR.PRIMARY}
size={DropdownToggle.SIZE.SMALL}
>
Dropdown toggle old button
</DropdownToggle>
// new button accepts a `variant` prop when `useNewButton` is true
<DropdownToggle
variant={DropdownToggle.VARIANT.TERTIARY}
size={DropdownToggle.SIZE.SMALL}
useNewButton
>
Dropdown toggle new button
</DropdownToggle>
Migrate to v2.0.0-beta.25
New buttons
A new Button
component is introduced to replace the various button components (these are deprecated but will stay available until GDS v3).
The components can be replaced as follows:
Old | New |
---|---|
<PrimaryButton /> | <Button variant={Button.VARIANT.PRIMARY} /> |
<SecondaryButton /> | <Button variant={Button.VARIANT.SECONDARY} /> |
<DangerButton /> | <Button variant={Button.VARIANT.DANGER} /> |
<TransparentButton /> | <Button variant={Button.VARIANT.SECONDARY} /> placed in a container with .g-inverted className |
<PrimaryIconButton icon={PrimaryIconButton.ICON.*} /> | <Button variant={Button.VARIANT.TERTIARY} icon={Button.ICON.*} /> |
<SecondaryIconButton icon={SecondaryIconButton.ICON.*} /> | <Button variant={Button.VARIANT.SECONDARY} icon={Button.ICON.*} /> |
<SecondaryIconButton outline={false} icon={SecondaryIconButton.ICON.*} /> | <Button variant={Button.VARIANT.TERTIARY} icon={Button.ICON.*} /> |
<TransparentIconButton icon={TransparentIconButton.ICON.*} /> | <Button variant={Button.VARIANT.SECONDARY} icon={Button.ICON.*} /> placed in a container with .g-inverted className |
<PrimaryLinkButton href="" /> | <Button variant={Button.VARIANT.TERTIARY} href="" /> |
<SecondaryLinkButton href="" /> | <Button variant={Button.VARIANT.TERTIARY} href="" /> |
<UIButton /> | <Button variant={Button.VARIANT.TERTIARY} /> |
<SegmentedButton /> | <Button /> in a <ButtonGroup segmented /> |
ButtonGroup
requires a little adjustment based on whether it contains the old or the new buttons.
The following button components remain to be used: ClearableButton
, CollapsibleButton
, DropdownActionButton
, FileListButton
, OverviewCardButton
, StripeActionButton
, ToggleButton
.
Migrate to v2.0.0-color.9
Breaking changes
- Replace George Pro colour
PRO
withG_PRO
. - Replace
$color-g-emerald
with$color-forest
, same applies to colour classes.g-bg-g-emerald
and.g-fg-g-emerald
. - Replace
$color-g-fog
with$color-stone
, same applies to colour classes.g-bg-g-fog
and.g-fg-g-fog
.
Deprecation summary
No immediate action required.
- All existing colour values have automatically mapped to the new reduced George colour palette. For details see old colour variables.
- Colour variables (
$color-g-*
) and their helper classes (.g-bg-g-*
/.g-fg-g-*
) have been deprecated. Switch to the new$color-*
variables and.g-bg-*
/.g-fg-*
helper classes. - CI colours (Erste Group colours) have been deprecated, use new colours according to the mapping.
- UI colours (Primary, Secondary, Grey, Active, Green, Red, Orange and Yellow) have been deprecated, use new colours according to the mapping.
- Colour variables (
Migrate to v2.0.0-beta.17
We’ve removed all the deprecations from last major release.
Amount
- Update
<Amount value={…} useSuperscript={false} />
to<Amount value={…} superscript={Amount.SUPERSCRIPT.DISABLED} />
- Update
<Amount value={…} forceSuperscript>
to<Amount value={…} superscript={Amount.SUPERSCRIPT.FORCED} />
Button
- StoreButton was removed, use PrimaryButton instead.
Card
- Update CardFooters which have set an amount or a button
- Update
<CardFooter amount={amount}>{label}</CardFooter>
to<CardFooter label={label} amount={amount} />
- Update
<CardFooter action={button}>{label}</CardFooter>
to<CardFooter label={label} action={button} />
- Update
- Update TransactionGroupFooters which have set an amount or a button
- Update
<TransactionGroupFooter amount={amount}>{label}</TransactionGroupFooter>
to<TransactionGroupFooter label={label} amount={amount} />
- Update
<TransactionGroupFooter action={button}>{label}</TransactionGroupFooter>
to<TransactionGroupFooter label={label} action={button} />
- Update
- Update LargeCardHeaders
Before
jsx<LargeCardHeader
backUrl={url}
backText={text}
backOnClick={onClick}
/>
After
jsx<LargeCardHeader left={
<UIButton href={url} onClick={onClick}>{text}</UIButton>
} />
Before
jsx<LargeCardHeader
buttonIcon={icon}
buttonText={text}
buttonOnClick={onClick}
buttonClassName={className}
/>
After
jsx<LargeCardHeader right={
<TransparentIconButton icon={icon} className={className} onClick={onClick}>{text}</TransparentIconButton>
} />
You can also use TransparentButton
Form
- Update
<FormField noLayout/>
to<FormField variant={FormField.VARIANT.NO_LAYOUT} />
Select
Before
jsx<ProductSelect items={[{ color: itemColor, … }]} />`
After
jsx<ProductSelect items={[{ product: { color: itemColor, … }, … }]} />
Before
jsx<RecipientSelect contactItems={[{ color: itemColor, … }]} />
After
jsx<ProductSelect contactItems={[{ product: { color: itemColor, … }, … }]} />
Migrate to v2.0.0-beta.15
LanguageProvider strings structure change
With a growing collection of components using strings the flat structure needed an upgrade. LanguageProvider now supports a deep object as strings
. See the following table and code examples on how to migrate your app.
DEPRECATED key | New key |
---|---|
actions | transaction.header.actions |
additionalInformation | transaction.header.misc |
amount | transaction.header.amount |
browseFiles | input.file.browse |
categoriesOrState | transaction.header.badges |
close | common.close |
collapse | common.collapse |
date | transaction.header.date |
dateButton | input.date.button |
delete | input.file.delete |
description | transaction.header.description |
details | transaction.header.details |
dragFiles | input.file.drag |
dropFiles | input.file.drop |
expand | common.expand |
help | common.help |
indicators | transaction.header.indicators |
loading | spinner.message |
optional | form.label.optional |
selectable | transaction.header.selectable |
selectAll | input.select.selectAll |
selectAllProducts | input.productSelect.selectAll |
selectedItems | input.select.selectedItems |
selectedProducts | input.productSelect.selectedItems |
stepperLabel | stepper.compactInfo |
title | transaction.header.title |
type | transaction.header.type |
uploading | input.file.uploading |
Before:
jsxconst strings = {
actions: 'Actions',
additionalInformation: 'Additional information',
amount: 'Amount',
browseFiles: 'Browse Files',
categoriesOrState: 'Categories/State',
close: 'Close',
collapse: 'Collapse',
date: 'Date',
dateButton: 'Choose a date',
delete: 'Delete',
description: 'Description',
details: 'Details',
dragFiles: 'Drag files here to upload or',
dropFiles: 'Drop files here',
expand: 'Expand',
help: 'Help',
indicators: 'Indicators',
loading: 'Loading...',
optional: 'Optional',
selectable: 'Select',
selectedItems: 'Selected multiple items',
selectedProducts: 'Selected multiple products',
selectAll: 'All items',
selectAllProducts: 'All products',
stepperLabel: 'Step {{currentStep}} of {{totalSteps}} – {{currentStepLabel}}',
title: 'Title',
type: 'Type',
uploading: 'Uploading...',
};
return (
<LanguageProvider locale="en" strings={strings}>
{children}
</LanguageProvider>
);
After:
jsxconst strings = {
common: {
close: 'Close',
collapse: 'Collapse',
expand: 'Expand',
help: 'Help',
},
form: {
label: {
optional: 'Optional',
},
},
input: {
date: {
button: 'Choose a date',
},
file: {
browse: 'Browse files',
delete: 'Delete',
drag: 'Drag files here to upload or',
drop: 'Drop files here',
uploading: 'Uploading...',
},
select: {
selectAll: 'All items',
selectedItems: 'Selected multiple items',
},
productSelect: {
selectAll: 'All products',
selectedItems: 'Selected multiple products',
},
},
spinner: {
message: 'Loading...',
},
stepper: {
compactInfo: 'Step {{currentStep}} of {{totalSteps}} – {{currentStepLabel}}',
},
transaction: {
header: {
date: 'Date',
title: 'Title',
description: 'Description',
amount: 'Amount',
type: 'Type',
badges: 'Categories/State',
indicators: 'Indicators',
misc: 'Additional information',
actions: 'Actions',
details: 'Details',
selectable: 'Select',
},
},
};
return (
<LanguageProvider locale="en" strings={strings}>
{children}
</LanguageProvider>
);
Migrate to v2.0.0-beta.12
ContactInfo
- Replace
useGroupIcon
prop withicon={ContactInfo.ICON.GROUP}
Snackbar enums
- Update
<SnackbarItem type={SnackbarItem.TYPE.X} />
to<SnackbarItem variant={SnackbarItem.VARIANT.X} />
Stripe
- Replace
stickyOffsets
prop withstickyOffset
Migrate to v2.0.0-beta.8
Misc enums
- Update
<Badge type={Badge.TYPE.X} />
to<Badge variant={Badge.VARIANT.X} />
- Update
<Pill type={Pill.TYPE.X} />
to<Pill variant={Pill.VARIANT.X} />
New default in FormField
- The default label position for large FormFields has changed. To keep the previous behaviour, update
<FormField variant={FormField.VARIANT.LARGE} />
to<FormField variant={FormField.VARIANT.LARGE} labelPosition={FormField.LABEL_POSITION.INSIDE} />
Migrate to v2.0.0-beta.6
Render props
All internal usages of render props throughout GDS have been standardized to use a single argument with properties instead of an unnamed argument list. Most components are unaffected by this, but if you are using one of the following props you need to adapt their signature as follows:
Component(s) | Prop | Signature change |
---|---|---|
All Select components | renderToggle | (selection) → ({ selection }) |
All Select components | renderSelection | (selection) → ({ selection }) |
All Select components | renderSelectableItemDecorator | (item) → ({ item }) |
Select, ProductSelect, MenuDropdown | renderItem | (item) → ({ item }) |
FilteredSelect, RecipientSelect | renderItem | (item, search) → ({ item, search }) |
MenuDropdown | renderItemsContainer | (children) → ({ children }) |
SelectableItem | renderDecorator | (value) → ({ value }) |
TableRow | render | (cells, props) → ({ cells, props }) |
TableCell | render | (children, props) → ({ children, props }) |
Alert enums
- Update
<Alert type={Alert.TYPE.X} />
to<Alert variant={Alert.VARIANT.X} />
- Update
<CollapsibleAlert type={CollapsibleAlert.TYPE.X} />
to<CollapsibleAlert variant={CollapsibleAlert.VARIANT.X} />
- Update
<ModalAlert type={ModalAlert.TYPE.X} />
to<ModalAlert variant={ModalAlert.VARIANT.X} />
EmptyState/StatusInfo & enums
- Update
<EmptyState type={EmptyState.TYPE.X} />
to<StatusInfo variant={StatusInfo.VARIANT.X} />
- Update
g-empty*
classes tog-status-info*
if used directly in your code
Migrate to v2.0.0-beta.4
LabeledList enums
A selection of boolean props have been reorganised into enums:
- replace
compact
prop withvariant={LabeledList.VARIANT.COMPACT}
- replace
separated={false}
prop withvariant={LabeledList.VARIANT.PLAIN}
- replace
striped
prop withvariant={LabeledList.VARIANT.STRIPED}
- replace
alignRight
prop withalignment={LabeledList.ALIGNMENT.RIGHT}
- replace
smallLabels
prop withlabelSize={LabeledList.LABEL_SIZE.SMALL}
Open/close handlers renaming
4 event handlers have been globally renamed to better reflect the underlying mechanic. The migration is straightforward (the order of operations is recommended):
- change
onOpen
prop toonBeforeOpen
- change
onOpened
prop toonOpen
- change
onClose
prop toonBeforeClose
- change
onClosed
prop toonClose
Affected components: Alert, CollapsibleAlert, CTAAlert, InputAlert, ModalAlert, Collapsible, Dropdown, ColorDropdown, MenuDropdown, FormField, Handover, DateInput, DateRangeInput, FileInput, HashtagInput, Modal, SecondaryNavigation, AmountDropdown, SegmentedMenu, FilteredSelect, ProductSelect, RecipientSelect, Snackbar, SnackbarItem, StripeNavigation, StripeHeader, CollapsibleTableRow, and AccountTransaction.
Migrate to v2.0.0-beta.0
Importing styles
With version 2.0, GDS component’s CSS has been removed from the JS bundle. Please import it in your project straight after gds-main.min.css
or gds-store.min.css
respectively
A minified version of this can be imported from here: @george-labs.com/design-system/dist/gds-components.min.css
So styles.scss
might end up looking something like this:
scss@import '~@george-labs.com/design-system/dist/bootstrap.min.css';
@import '~@george-labs.com/design-system/dist/gds-main.min.css';
@import '~@george-labs.com/design-system/dist/gds-components.min.css';
Bootstrap 4.5
With version 2.0, GDS has updated its Bootstrap dependency to 4.5. A lot has changed since v4.0-alpha.6, so please refer to external migration guides to update your classes accordingly:
Notable changes in GDS components:
Col push
and pull
aren’t supported in Bootstrap anymore. Please use offset
if you want to shift a column and order
if you want to order it differently from how they appear in the markup.
InputGroup styles have changed significantly, and require specific classes to work seamlessly. GDS tries to apply those classes automatically, but if you wrap our components you might run into problems. Please add a static property to your wrapper so that GDS knows how to deal with that addon.
jsxconst SelectWrapper = ({ ...rest }) => <Select {...rest} />;
SelectWrapper.wrapsComponent = Select;
Currently supported addons:
- Text
- Button components
- Select components
Small Paragraphs
To add a paragraph with smaller text to George Web, the inline HTML element small
has been used, which then was rendered as a paragraph with margins and a decreased font size. This has been wrong for two reasons. For starters, <small>
is not a block-level but an inline element, and should be placed inside a proper block-level parent, usually a paragraph. And more importantly, <small>
is the wrong element to begin with. According to MDN,
the HTML
<small>
element represents side-comments and small print, like copyright and legal text, independent of its styled presentation.
Starting with GDS 2.0, all occurrences of <small>
need to be replaced with Paragraphs that have a .g-small
modifier class added. There might be cases where the <small>
element should be kept for semantic reasons, but chances on that are slim to nil. Legal text usually comes preformatted from the Copywriter’s CMS. That said, even if such cases exist, they still need to be wrapped in the aforementioned way.
Toggle
Toggle components have been turned into inline elements. To reinstate the former behaviour, ToggleIcon, ToggleImage and most likely also ToggleButton need to be wrapped inside e.g. a paragraph. As ToggleIcons and ToggleImages mainly come in groups of two or three, this is especially important on tier XS
, where they are displayed vertically: If you do not wrap each one inside a paragraph, they end up not having enough margin between them. Other parent elements may also work, whatever makes sense semantically.
The newly introduced ToggleBadge should be inline anyway, so you may not need to add any parent element, but better cross-check.
Avatar
PunchedImage has been renamed to Avatar and its style has been updated. All functionalities remain the same as before.
GDS Styles
PunchedImage (old) | Avatar (new) |
---|---|
.g-punched | .g-avatar |
.g-punched-content | .g-avatar-content |
.g-punched-image | .g-avatar-image |
.g-punched-icon | .g-avatar-icon |
.g-punched-hover | .g-avatar-hover |
.g-punched-badge | .g-avatar-badge |
Alert variants
CTAAlert and InputAlert components are deprecated in favour of using a new size
prop in the Alert component. Migration is straightforward:
- change
<CTAAlert {...rest} />
to<Alert size={Alert.SIZE.LARGE} {...rest} />
- change
<InputAlert {...rest} />
to<Alert size={Alert.SIZE.SMALL} {...rest} />
Migrate to v1.0.0-beta.2
Removal of deprecated features
GDS Styles
Removed | Alternative |
---|---|
.g-product-info-data .g-amount | .g-product-info-horizontal .g-product-info-display (see documentation) |
.g-product-info-amount-right | (requires same solution as .g-product-info-data .g-amount , see above) |
Deprecated features
GDS Components
Deprecated | Alternative |
---|---|
ProductInfo.amountRight | no longer possible for vertical ProductInfos, and automatically happening when ProductInfo.horizontal is set |
Migrate to v1.0.0-beta.0
While it took some time to merge George Styleguide and George Components into George Design System, it shouldn’t be much of an effort for you to migrate to our newest release.
NPM package
Now that George Styleguide (george-styleguide
) and George Components (george-components
) are provided via a single NPM package (@george-labs.com/design-system) all imports in your project need to be changed to use the new repository.
There’s two things that need to be done now:
- Delete both
george-styleguide
andgeorge-components
dependencies - Add
@george-labs.com/design-system
as a dependency
bashnpm add @george-labs.com/design-system
GDS Styles
All assets and SASS files still live in the same folder than before, so only the dependency name needs to be changed, the path should stay the same, except for the following theme files:
Old theme | New theme |
---|---|
sass/george-bs4-theme.scss | sass/gds-main.scss |
sass/george-store-theme.scss | sass/gds-store.scss |
sass/george-sanity-theme.scss | sass/gds-sanity.scss |
Before:
scss@import '~george-styleguide/sass/common';
@import '~george-styleguide/sass/george-bs4-theme';
@import '~george-styleguide/assets/fonts/styleguide/styleguide.css';
// ...
After:
scss@import '~@george-labs.com/design-system/sass/common';
@import '~@george-labs.com/design-system/sass/gds-main';
@import '~@george-labs.com/design-system/assets/fonts/styleguide/styleguide.css';
// ...
GDS Components
The GDS JS module exports all components exactly the same way than before, so a search/replace over george-components
should be enough. Typescript type definitions should work out of the box as well.
Before:
jsximport { Card } from 'george-components';
// ...
After:
jsximport { Card } from '@george-labs.com/design-system';
// ...
Renamed assets
Assets renamed to use gds
prefix. The following include paths need to be adjusted:
/assets/george-icons.svg
→ BREAKING removed/assets/george-icons-new.svg
→/assets/gds-icons.svg
/assets/george-loading.svg
→/assets/gds-loading.svg
Bootstrap, Compiled CSS and Autoprefixer
As of GDS 1.0.0, SASS files won’t be using vendor prefixes anymore. They will be added automatically by Autoprefixer in combination with a browserlist
entry in our package.json
file on build.
What this means:
- SASS files shouldn’t be imported directly anymore if they are expected to be vendor-prefixed
- Instead we provide a compiled CSS version (including sourcmap files) of the theme in the
dist
folder - Variables, functions and mixins can still be used without any repercussions by importing
sass/common
- Should it be necessary to import the SASS files somehow, they would have to be vendor-prefixed the build process of your project
Theme (unprefixed) | Compiled CSS (prefixed) |
---|---|
sass/gds-main.scss | dist/gds-main.css |
sass/gds-store.scss | dist/gds-store.css |
sass/gds-sanity.scss | dist/gds-sanity.css |
In addition to that, we now also provide a stripped down, compiled version of Bootstrap. This file is already namespaced with .g-bootstrap
.
Before:
scss.g-bootstrap {
@import '../../../../node_modules/george-styleguide/node_modules/bootstrap/scss/bootstrap';
// 🤷♂️
}
After:
scss@import '~@george-labs.com/design-system/dist/bootstrap.css';
// ... or the SASS version (without prefixes) ...
@import '~@george-labs.com/design-system/sass/bootstrap';
Removal of deprecated features
GDS Styles
Removed | Alternative |
---|---|
.g-dropdown-product-simple | .g-dropdown-product (see documentation) |
.g-dropdown-account-simple | .g-dropdown-product (see documentation) |
.g-alert-danger | .g-alert-error (see documentation) |
GDS Components
Removed | Alternative |
---|---|
Alert.TYPE.DANGER | Alert.TYPE.ERROR |
Icon.name | Icon.icon |
PunchedImage.iconHover | PunchedImage.hoverIcon |
PunchedImage.iconBadge | PunchedImage.badgeIcon |
AmountInput.amountObject | AmountInput.value , AmountInput.precision , AmountInput.currency |
AmountInput.onInputBlur | AmountInput.onBlur , AmountInput.onFormat , AmountInput.onInput |
AmountInput.onInputFocus | AmountInput.onFocus |
Badge.variation | Badge.type |
Pill.variation | Pill.type |
MoneyFormatter | Amount |
formatMoney | formatAmount |