Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
163 changes: 163 additions & 0 deletions docs/guides/upgrade-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,169 @@ type: embed

```

### BaseButton / Button / IconButton / CondensedButton

All button components share the same `BaseButton` theme.

- `Button` and `CondensedButton` `size` prop now also accepts `'condensedSmall'` and `'condensedMedium'` values.
- Icon sizing is no longer controlled by theme variables (`iconSizeSmall`, `iconSizeMedium`, `iconSizeLarge`). Icons are now sized via the `renderIconWithProps` utility.
- Per-size vertical padding variables (`smallPaddingTop`, `smallPaddingBottom`, etc.) have been replaced by a single `paddingVertical` variable.
- Active state box-shadow variables have been replaced by explicit border/text color variables for each state.
- New disabled state variables provide per-color-variant control instead of the previous blanket opacity approach.

```js
---
type: embed
---
<V12ChangelogTable
added={[
{name:"paddingVertical",note:"replaces per-size top/bottom padding"},
{name:"gapButtonContentSm",note:"replaces iconTextGapCondensed"},
{name:"gapButtonContentMd",note:"replaces iconTextGap"},
{name:"gapButtonContentLg",note:"replaces iconTextGap"},
{name:"heightXxs",note:"height for condensedSmall size"},
{name:"heightXs",note:"height for condensedMedium size"},
{name:"borderRadiusFull",note:"full/pill border radius"},
{name:"borderRadiusSm",note:"small border radius"},
{name:"opacityBase",note:"base opacity value"},
{name:"opacityDisabled",note:"disabled state opacity"},
{name:"primaryActiveBorderColor",note:""},
{name:"primaryActiveTextColor",note:""},
{name:"primaryHoverBorderColor",note:""},
{name:"primaryHoverTextColor",note:""},
{name:"primaryDisabledBackgroundColor",note:""},
{name:"primaryDisabledBorderColor",note:""},
{name:"primaryDisabledTextColor",note:""},
{name:"primaryOnColorActiveBorderColor",note:""},
{name:"primaryOnColorActiveTextColor",note:""},
{name:"primaryOnColorHoverBorderColor",note:""},
{name:"primaryOnColorHoverTextColor",note:""},
{name:"primaryOnColorDisabledBackgroundColor",note:""},
{name:"primaryOnColorDisabledBorderColor",note:""},
{name:"primaryOnColorDisabledTextColor",note:""},
{name:"secondaryActiveBorderColor",note:""},
{name:"secondaryActiveTextColor",note:""},
{name:"secondaryHoverBorderColor",note:""},
{name:"secondaryHoverTextColor",note:""},
{name:"secondaryDisabledBackgroundColor",note:""},
{name:"secondaryDisabledBorderColor",note:""},
{name:"secondaryDisabledTextColor",note:""},
{name:"secondaryOnColorActiveBorderColor",note:""},
{name:"secondaryOnColorActiveTextColor",note:""},
{name:"secondaryOnColorHoverBorderColor",note:""},
{name:"secondaryOnColorHoverTextColor",note:""},
{name:"secondaryOnColorDisabledBorderColor",note:""},
{name:"secondaryOnColorDisabledTextColor",note:""},
{name:"tertiaryActiveBorderColor",note:""},
{name:"tertiaryActiveTextColor",note:""},
{name:"tertiaryHoverBorderColor",note:""},
{name:"tertiaryHoverTextColor",note:""},
{name:"tertiaryDisabledBorderColor",note:""},
{name:"tertiaryDisabledTextColor",note:""},
{name:"ghostOncolorActiveBackgroundColor",note:""},
{name:"ghostOncolorHoverBackgroundColor",note:""},
{name:"successActiveBorderColor",note:""},
{name:"successActiveTextColor",note:""},
{name:"successHoverBorderColor",note:""},
{name:"successHoverTextColor",note:""},
{name:"successDisabledBackgroundColor",note:""},
{name:"successDisabledBorderColor",note:""},
{name:"successDisabledTextColor",note:""},
{name:"successSecondaryActiveBorderColor",note:""},
{name:"successSecondaryActiveTextColor",note:""},
{name:"successSecondaryHoverBorderColor",note:""},
{name:"successSecondaryHoverTextColor",note:""},
{name:"successSecondaryDisabledBorderColor",note:""},
{name:"successSecondaryDisabledTextColor",note:""},
{name:"destructiveActiveBorderColor",note:""},
{name:"destructiveActiveTextColor",note:""},
{name:"destructiveHoverBorderColor",note:""},
{name:"destructiveHoverTextColor",note:""},
{name:"destructiveDisabledBackgroundColor",note:""},
{name:"destructiveDisabledBorderColor",note:""},
{name:"destructiveDisabledTextColor",note:""},
{name:"destructiveSecondaryActiveBorderColor",note:""},
{name:"destructiveSecondaryActiveTextColor",note:""},
{name:"destructiveSecondaryHoverBorderColor",note:""},
{name:"destructiveSecondaryHoverTextColor",note:""},
{name:"destructiveSecondaryDisabledBorderColor",note:""},
{name:"destructiveSecondaryDisabledTextColor",note:""},
{name:"aiBaseTextColor",note:""},
{name:"aiActiveTextColor",note:""},
{name:"aiHoverTextColor",note:""},
{name:"aiActiveBackgroundTopGradientColor",note:""},
{name:"aiActiveBackgroundBottomGradientColor",note:""},
{name:"aiActiveBorderTopGradientColor",note:""},
{name:"aiActiveBorderBottomGradientColor",note:""},
{name:"aiHoverBackgroundTopGradientColor",note:""},
{name:"aiHoverBackgroundBottomGradientColor",note:""},
{name:"aiHoverBorderTopGradientColor",note:""},
{name:"aiHoverBorderBottomGradientColor",note:""},
{name:"aiDisabledBackgroundColor",note:""},
{name:"aiDisabledBorderColor",note:""},
{name:"aiDisabledTextColor",note:""},
{name:"aiSecondaryActiveBackgroundTopGradientColor",note:""},
{name:"aiSecondaryActiveBackgroundBottomGradientColor",note:""},
{name:"aiSecondaryHoverBackgroundTopGradientColor",note:""},
{name:"aiSecondaryHoverBackgroundBottomGradientColor",note:""},
{name:"aiSecondaryDisabledBorderColor",note:""},
{name:"aiSecondaryDisabledTextColor",note:""},
{name:"aiSecondaryTextTopGradientColor",note:""},
{name:"aiSecondaryTextBottomGradientColor",note:""}
]}
removed={[
{name:"smallPaddingTop",note:"replaced by paddingVertical"},
{name:"smallPaddingBottom",note:"replaced by paddingVertical"},
{name:"mediumPaddingTop",note:"replaced by paddingVertical"},
{name:"mediumPaddingBottom",note:"replaced by paddingVertical"},
{name:"largePaddingTop",note:"replaced by paddingVertical"},
{name:"largePaddingBottom",note:"replaced by paddingVertical"},
{name:"iconSizeSmall",note:"icon sizing now handled via renderIconWithProps"},
{name:"iconSizeMedium",note:"icon sizing now handled via renderIconWithProps"},
{name:"iconSizeLarge",note:"icon sizing now handled via renderIconWithProps"},
{name:"iconTextGap",note:"replaced by gapButtonContentMd / gapButtonContentLg"},
{name:"iconTextGapCondensed",note:"replaced by gapButtonContentSm"},
{name:"primaryActiveBoxShadow",note:"replaced by primaryActiveBorderColor / primaryActiveTextColor"},
{name:"primaryGhostActiveBoxShadow",note:""},
{name:"primaryGhostBoxShadow",note:""},
{name:"primaryGhostHoverBoxShadow",note:""},
{name:"secondaryActiveBoxShadow",note:"replaced by secondaryActiveBorderColor / secondaryActiveTextColor"},
{name:"secondaryGhostActiveBoxShadow",note:""},
{name:"successActiveBoxShadow",note:"replaced by successActiveBorderColor / successActiveTextColor"},
{name:"successGhostActiveBoxShadow",note:""},
{name:"dangerActiveBoxShadow",note:"replaced by destructiveActiveBorderColor / destructiveActiveTextColor"},
{name:"dangerGhostActiveBoxShadow",note:""},
{name:"primaryInverseActiveBoxShadow",note:"replaced by primaryOnColorActiveBorderColor / primaryOnColorActiveTextColor"},
{name:"primaryInverseGhostActiveBoxShadow",note:""},
{name:"aiActiveBoxShadow",note:"replaced by individual AI active gradient variables"}
]}
changed={[
{oldName:"iconTextGap",newName:"gapButtonContentMd / gapButtonContentLg",note:"size-specific gap tokens"},
{oldName:"iconTextGapCondensed",newName:"gapButtonContentSm",note:""}
]}
/>

```

### CloseButton

CloseButton no longer has its own theme type. It now uses `BaseButton`'s theme (see above). The old `CloseButtonTheme` variables for offset and z-index have been removed — offsets are now read from shared spacing tokens and z-index is hardcoded.

```js
---
type: embed
---
<V12ChangelogTable
removed={[
{name:"offsetMedium",note:"now uses sharedTokens spacing"},
{name:"offsetSmall",note:"now uses sharedTokens spacing"},
{name:"offsetXSmall",note:"now uses sharedTokens spacing"},
{name:"zIndex",note:"hardcoded to 1"}
]}
/>

```

### Billboard

```js
Expand Down
8 changes: 1 addition & 7 deletions packages/shared-types/src/ComponentThemeVariables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -267,12 +267,6 @@ export type BaseButtonTheme = {
aiActiveBoxShadow: string
}

export type CloseButtonTheme = {
offsetMedium: Spacing['medium']
offsetSmall: Spacing['small']
offsetXSmall: Spacing['xSmall']
zIndex: Stacking['above']
}

export type BylineTheme = {
fontFamily: Typography['fontFamily']
Expand Down Expand Up @@ -1803,7 +1797,7 @@ export interface ThemeVariables {
Breadcrumb: BreadcrumbTheme
BaseButton: BaseButtonTheme
Button: BaseButtonTheme
CloseButton: CloseButtonTheme
Comment on lines 1805 to -1806
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

import type { CloseButtonTheme } from '@instructure/shared-types' was removed from styles.ts of CloseButton, why was this change needed?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there is not closebuttontheme anymore, it does not have its own variables

CloseButton: BaseButtonTheme
CondensedButton: BaseButtonTheme
IconButton: BaseButtonTheme
Byline: BylineTheme
Expand Down
36 changes: 28 additions & 8 deletions packages/ui-buttons/src/BaseButton/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ import keycode from 'keycode'
import {
getElementType,
getInteraction,
passthroughProps,
callRenderProp
passthroughProps
} from '@instructure/ui-react-utils'
import { isActiveElement } from '@instructure/ui-dom-utils'
import { hasVisibleChildren } from '@instructure/ui-a11y-utils'
import { renderIconWithProps } from '@instructure/ui-icons'
import { View } from '@instructure/ui-view'
import type { ViewProps } from '@instructure/ui-view'

Expand All @@ -41,21 +41,37 @@ import type { ViewProps } from '@instructure/ui-view'
import { isSafari } from '@instructure/ui-utils'
import { combineDataCid } from '@instructure/ui-utils'

import { withStyleRework as withStyle } from '@instructure/emotion'
import { withStyle } from '@instructure/emotion'

import generateStyles from './styles'
import generateComponentTheme from './theme'

import { allowedProps } from './props'
import type { BaseButtonProps, BaseButtonStyleProps } from './props'

const buttonSizeToIconSize = {
small: 'sm',
medium: 'md',
large: 'lg',
condensedSmall: 'xs',
condensedMedium: 'xs'
} as const

const buttonColorToIconColor = {
'primary': 'inherit',
'primary-inverse': 'inherit',
'secondary': 'inherit',
'success': 'inherit',
'danger': 'inherit',
'ai-primary': 'inherit',
'ai-secondary': 'ai'
} as const

/**
---
category: components/utilities
---
**/

@withStyle(generateStyles, generateComponentTheme)
@withStyle(generateStyles)
class BaseButton extends Component<BaseButtonProps> {
static readonly componentId = 'BaseButton'

Expand Down Expand Up @@ -201,7 +217,7 @@ class BaseButton extends Component<BaseButtonProps> {
}

renderChildren() {
const { renderIcon, children, styles } = this.props
const { renderIcon, children, styles, size, color } = this.props

const wrappedChildren = <span css={styles?.children}>{children}</span>

Expand All @@ -210,8 +226,12 @@ class BaseButton extends Component<BaseButtonProps> {
}

const { hasOnlyIconVisible } = this
const iconSize = buttonSizeToIconSize[size!]
const iconColor = buttonColorToIconColor[color!]
const wrappedIcon = (
<span css={styles?.iconSVG}>{callRenderProp(renderIcon)}</span>
<span css={styles?.iconSVG}>
{renderIconWithProps(renderIcon, iconSize, iconColor)}
</span>
)

const flexChildren = hasOnlyIconVisible ? (
Expand Down
2 changes: 1 addition & 1 deletion packages/ui-buttons/src/BaseButton/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ type BaseButtonOwnProps = {
/**
* The size of the `Button`
*/
size?: 'small' | 'medium' | 'large'
size?: 'small' | 'medium' | 'large' | 'condensedSmall' | 'condensedMedium'

Comment on lines +56 to 57
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In Basebutton a size and color combination of like this below results some invisible button when it is not hovered. (Not sure if it a valid use case tho)

<BaseButton size="condensedSmall" color="primary">CS</BaseButton>

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i guess this is not a valid state so i don't know how big of a deal this is. cc @hajnaldo

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hajnaldo confirmed this combination should never exist

/**
* Provides a reference to the `Button`'s underlying html element.
Expand Down
Loading