diff --git a/docs/guides/upgrade-guide.md b/docs/guides/upgrade-guide.md
index 181509b98c..78d20542a3 100644
--- a/docs/guides/upgrade-guide.md
+++ b/docs/guides/upgrade-guide.md
@@ -95,6 +95,23 @@ type: embed
```
+### Billboard
+
+```js
+---
+type: embed
+---
+
+
+```
+
### Breadcrumb
```js
diff --git a/packages/ui-billboard/src/Billboard/README.md b/packages/ui-billboard/src/Billboard/README.md
index 06f20b5c31..7bb6a011b4 100644
--- a/packages/ui-billboard/src/Billboard/README.md
+++ b/packages/ui-billboard/src/Billboard/README.md
@@ -43,7 +43,7 @@ type: example
onClick={function () {
alert('This Billboard was clicked!')
}}
- hero={(size) => }
+ hero={(size) => }
/>
```
@@ -57,7 +57,7 @@ type: example
margin="large"
message="Click this link"
href="http://instructure.com"
- hero={(size) => }
+ hero={(size) => }
/>
```
@@ -73,7 +73,7 @@ type: example
onClick={function () {
alert('This Billboard was clicked!')
}}
- hero={(size) => }
+ hero={(size) => }
/>
```
@@ -89,7 +89,7 @@ type: example
onClick={function () {
alert('This Billboard was clicked!')
}}
- hero={(size) => }
+ hero={(size) => }
disabled
/>
```
diff --git a/packages/ui-billboard/src/Billboard/index.tsx b/packages/ui-billboard/src/Billboard/index.tsx
index 1c6f673126..976c2c7b53 100644
--- a/packages/ui-billboard/src/Billboard/index.tsx
+++ b/packages/ui-billboard/src/Billboard/index.tsx
@@ -31,23 +31,33 @@ import {
callRenderProp,
getElementType
} from '@instructure/ui-react-utils'
+import { renderIconWithProps } from '@instructure/ui-icons'
-import { withStyleRework as withStyle } from '@instructure/emotion'
+import { withStyle } from '@instructure/emotion'
import generateStyle from './styles'
-import generateComponentTheme from './theme'
import { allowedProps } from './props'
-import type { BillboardProps, HeroIconSize } from './props'
+import type { BillboardProps } from './props'
import type { ViewProps } from '@instructure/ui-view'
+// Map Billboard sizes to Lucide icon sizes
+const billboardSizeToIconSize = {
+ small: 'illu-sm',
+ medium: 'illu-md',
+ large: 'illu-lg'
+} as const
+
/**
---
category: components
---
**/
-@withStyle(generateStyle, generateComponentTheme)
-class Billboard extends Component {
+@withStyle(generateStyle)
+class Billboard extends Component<
+ BillboardProps,
+ { isHovered: boolean; isActive: boolean }
+> {
static readonly componentId = 'Billboard'
static allowedProps = allowedProps
@@ -61,6 +71,11 @@ class Billboard extends Component {
elementRef: () => {}
} as const
+ state = {
+ isHovered: false,
+ isActive: false
+ }
+
ref: Element | null = null
handleRef = (el: Element | null) => {
@@ -93,25 +108,37 @@ class Billboard extends Component {
)
}
- get SVGIconSize(): HeroIconSize {
- const size = this.props.size
+ handleMouseEnter = () => {
+ this.setState({ isHovered: true })
+ }
- // serve up appropriate SVGIcon size for each Billboard size
- if (size === 'small') {
- return 'medium'
- } else if (size === 'large') {
- return 'x-large'
- } else {
- return 'large'
- }
+ handleMouseLeave = () => {
+ this.setState({ isHovered: false, isActive: false })
+ }
+
+ handleMouseDown = () => {
+ this.setState({ isActive: true })
+ }
+
+ handleMouseUp = () => {
+ this.setState({ isActive: false })
}
renderHero() {
- if (typeof this.props.hero === 'function') {
- return this.props.hero(this.SVGIconSize)
- } else {
- return this.props.hero
- }
+ const { hero, size } = this.props
+ const { isHovered, isActive } = this.state
+
+ if (!hero) return null
+
+ const lucideSize = billboardSizeToIconSize[size!]
+ // Priority: active > hover > default
+ const iconColor = isActive
+ ? 'onColor'
+ : isHovered
+ ? 'infoColor'
+ : 'baseColor'
+
+ return renderIconWithProps(hero, lucideSize, iconColor)
}
renderContent() {
@@ -157,6 +184,10 @@ class Billboard extends Component {
css={styles?.billboard}
href={href}
onClick={this.handleClick}
+ onMouseEnter={this.handleMouseEnter}
+ onMouseLeave={this.handleMouseLeave}
+ onMouseDown={this.handleMouseDown}
+ onMouseUp={this.handleMouseUp}
disabled={disabled}
aria-disabled={disabled || readOnly ? 'true' : undefined}
>
diff --git a/packages/ui-billboard/src/Billboard/props.ts b/packages/ui-billboard/src/Billboard/props.ts
index f1a6755902..b43946762c 100644
--- a/packages/ui-billboard/src/Billboard/props.ts
+++ b/packages/ui-billboard/src/Billboard/props.ts
@@ -40,7 +40,7 @@ type BillboardOwnProps = {
/**
* Provide an
component or Instructure Icon for the hero image
*/
- hero?: React.ReactElement | ((iconSize: HeroIconSize) => React.ReactElement)
+ hero?: React.ReactElement | ((iconSize?: HeroIconSize) => React.ReactElement)
/**
* If you're using an icon, this prop will size it. Also sets the font-size
* of the headline and message.
diff --git a/packages/ui-billboard/src/Billboard/styles.ts b/packages/ui-billboard/src/Billboard/styles.ts
index 3ba329f795..7ea4965a79 100644
--- a/packages/ui-billboard/src/Billboard/styles.ts
+++ b/packages/ui-billboard/src/Billboard/styles.ts
@@ -22,8 +22,8 @@
* SOFTWARE.
*/
-import type { BillboardTheme } from '@instructure/shared-types'
import type { BillboardProps, BillboardStyle } from './props'
+import type { NewComponentTypes } from '@instructure/ui-themes'
/**
* ---
@@ -36,7 +36,7 @@ import type { BillboardProps, BillboardStyle } from './props'
* @return {Object} The final style object, which will be used in the component
*/
const generateStyle = (
- componentTheme: BillboardTheme,
+ componentTheme: NewComponentTypes['Billboard'],
props: BillboardProps
): BillboardStyle => {
const { size, href, onClick, disabled, hero, heading } = props
@@ -83,15 +83,11 @@ const generateStyle = (
'&:hover, &:focus': {
textDecoration: 'none',
outline: 'none',
- borderColor: componentTheme.iconHoverColor,
-
- '& [class$=-billboard__hero]': {
- color: componentTheme.iconHoverColor
- }
+ borderColor: componentTheme.messageColorClickable
},
'&:active': {
background: componentTheme.clickableActiveBg,
- borderColor: componentTheme.iconHoverColor,
+ borderColor: componentTheme.messageColorClickable,
'& [class$=-billboard__hero], & [class$=-billboard__message]': {
color: componentTheme.clickableActiveText
@@ -128,7 +124,6 @@ const generateStyle = (
hero: {
label: 'billboard__hero',
display: 'block',
- color: componentTheme.iconColor,
...sizeVariants[size!].hero,
'& > img, & > svg': {
diff --git a/packages/ui-billboard/src/Billboard/theme.ts b/packages/ui-billboard/src/Billboard/theme.ts
deleted file mode 100644
index 49a8212c7b..0000000000
--- a/packages/ui-billboard/src/Billboard/theme.ts
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2015 - present Instructure, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-/* Global variables (colors, typography, spacing, etc.) are defined in lib/themes */
-
-import type { Theme, ThemeSpecificStyle } from '@instructure/ui-themes'
-import { BillboardTheme } from '@instructure/shared-types'
-
-/**
- * Generates the theme object for the component from the theme and provided additional information
- * @param {Object} theme The actual theme object.
- * @return {Object} The final theme object with the overrides and component variables
- */
-const generateComponentTheme = (theme: Theme): BillboardTheme => {
- const { borders, colors, spacing, typography, key: themeName } = theme
-
- const themeSpecificStyle: ThemeSpecificStyle = {
- canvas: {
- iconHoverColor: theme['ic-link-color'],
- messageColorClickable: theme['ic-link-color'],
- clickableActiveBg: theme['ic-brand-primary']
- }
- }
-
- const componentVariables: BillboardTheme = {
- fontFamily: typography?.fontFamily,
- paddingSmall: spacing?.small,
- paddingMedium: spacing?.medium,
- paddingLarge: spacing?.medium,
- iconColor: colors?.contrasts?.grey4570,
- mediumMargin: spacing?.small,
- largeMargin: spacing?.medium,
- iconHoverColor: colors?.contrasts?.blue4570,
- backgroundColor: colors?.contrasts?.white1010,
- iconHoverColorInverse: colors?.contrasts?.white1010,
- buttonBorderWidth: borders?.widthMedium,
- buttonBorderRadius: borders?.radiusLarge,
- messageColor: colors?.contrasts?.blue4570,
- messageColorClickable: colors?.contrasts?.blue4570,
- messageColorInverse: colors?.contrasts?.grey1111,
- messageFontSizeSmall: typography?.fontSizeSmall,
- messageFontSizeMedium: typography?.fontSizeMedium,
- messageFontSizeLarge: typography?.fontSizeLarge,
- clickableActiveBg: colors?.contrasts?.blue4570,
- clickableActiveText: colors?.contrasts?.white1010,
- buttonBorderStyle: borders?.style,
- buttonHoverBorderStyle: 'dashed'
- }
-
- return {
- ...componentVariables,
- ...themeSpecificStyle[themeName]
- }
-}
-
-export default generateComponentTheme
diff --git a/packages/ui-icons/src/lucide/wrapLucideIcon/props.ts b/packages/ui-icons/src/lucide/wrapLucideIcon/props.ts
index f6c0c79194..f6e8937425 100644
--- a/packages/ui-icons/src/lucide/wrapLucideIcon/props.ts
+++ b/packages/ui-icons/src/lucide/wrapLucideIcon/props.ts
@@ -48,7 +48,17 @@ type LegacyColorTokens =
/**
* Semantic size tokens for icons - includes SVGIcon legacy tokens, they are DEPRECATED and will be deleted, DON'T USE THEM.
*/
-type IconSizeToken = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | SVGIconSizeToken
+type IconSizeToken =
+ | 'xs'
+ | 'sm'
+ | 'md'
+ | 'lg'
+ | 'xl'
+ | '2xl'
+ | 'illu-sm'
+ | 'illu-md'
+ | 'illu-lg'
+ | SVGIconSizeToken
/**
* Semantic color tokens from Icon theme
diff --git a/packages/ui-icons/src/lucide/wrapLucideIcon/styles.ts b/packages/ui-icons/src/lucide/wrapLucideIcon/styles.ts
index 21b587f4a8..b7a59c0feb 100644
--- a/packages/ui-icons/src/lucide/wrapLucideIcon/styles.ts
+++ b/packages/ui-icons/src/lucide/wrapLucideIcon/styles.ts
@@ -51,6 +51,9 @@ const convertSemanticSize = (
lg: componentTheme.sizeLg,
xl: componentTheme.sizeXl,
'2xl': componentTheme.size2xl,
+ 'illu-sm': componentTheme.illuSm,
+ 'illu-md': componentTheme.illuMd,
+ 'illu-lg': componentTheme.illuLg,
// Legacy SVGIcon size tokens (DEPRECATED)
'x-small': '1.125rem',
small: '2rem',
@@ -78,6 +81,9 @@ const convertSizeToStrokeWidth = (
lg: componentTheme.strokeWidthLg,
xl: componentTheme.strokeWidthXl,
'2xl': componentTheme.strokeWidth2xl,
+ 'illu-sm': componentTheme.strokeWidthIlluSm,
+ 'illu-md': componentTheme.strokeWidthIlluMd,
+ 'illu-lg': componentTheme.strokeWidthIlluLg,
// Legacy SVGIcon stroke tokens (DEPRECATED)
'x-small': '0.0859375rem',
small: '0.15625rem',