Skip to content
Merged
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
15 changes: 14 additions & 1 deletion packages/ui-heading/src/Heading/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,20 @@ type: example
<Heading>I inherit my color via the CSS cascade (default)</Heading>
<Heading color="primary">I am primary color</Heading>
<Heading color="secondary">I am secondary color</Heading>
<Heading color="ai"><IconAiColoredSolid/>&nbsp; I am AI color</Heading>
<Heading color="ai">I am AI color</Heading>
</div>
```

### Icons

With the `renderIcon` prop, an icon can be rendered before the text. Only current use-case is for the `ai heading`

```js
---
type: example
---
<div>
<Heading color="ai" renderIcon={<IconAiColoredSolid/>}>I am AI color with icon</Heading>
</div>
```

Expand Down
21 changes: 19 additions & 2 deletions packages/ui-heading/src/Heading/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@
import { Component } from 'react'

import { View } from '@instructure/ui-view'
import { getElementType, passthroughProps } from '@instructure/ui-react-utils'
import {
getElementType,
passthroughProps,
callRenderProp
} from '@instructure/ui-react-utils'
import { testable } from '@instructure/ui-testable'

import { withStyle } from '@instructure/emotion'
Expand Down Expand Up @@ -105,6 +109,19 @@ class Heading extends Component<HeadingProps> {
this.checkProps()
}

renderContent() {
const { children, renderIcon } = this.props

if (renderIcon) {
return (
<>
{callRenderProp(renderIcon)}&nbsp;{children}
</>
)
}
return children
}

render() {
const {
border,
Expand Down Expand Up @@ -139,7 +156,7 @@ class Heading extends Component<HeadingProps> {
elementRef={this.handleRef}
margin={margin}
>
{children}
{this.renderContent()}
</View>
)
}
Expand Down
8 changes: 7 additions & 1 deletion packages/ui-heading/src/Heading/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ import type {
AsElementType,
PropValidators,
HeadingTheme,
OtherHTMLAttributes
OtherHTMLAttributes,
Renderable
} from '@instructure/shared-types'
import type {
Spacing,
Expand Down Expand Up @@ -78,6 +79,10 @@ type HeadingOwnProps = {
* Provides a ref to the underlying HTML element
*/
elementRef?: (element: Element | null) => void
/**
* An icon, or function that returns an icon that gets displayed before the text.
*/
renderIcon?: Renderable
/**
* Sets style and level at once. The as property will be the same as the level.
* NOTE: this is the recommended way of setting the appearance, instead of level
Expand Down Expand Up @@ -120,6 +125,7 @@ const propTypes: PropValidators<PropKeys> = {
as: PropTypes.elementType,
margin: PropTypes.string,
elementRef: PropTypes.func,
renderIcon: PropTypes.oneOfType([PropTypes.node, PropTypes.func]),
variant: PropTypes.oneOf([
'titlePageDesktop',
'titlePageMobile',
Expand Down
12 changes: 8 additions & 4 deletions packages/ui-heading/src/Heading/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ const generateStyle = (
componentTheme: HeadingTheme,
props: HeadingProps
): HeadingStyle => {
const { level, color, border, variant } = props
const { level, color, border, variant, renderIcon } = props

const variants: Record<NonNullable<HeadingProps['variant']>, object> = {
titlePageDesktop: {
Expand Down Expand Up @@ -188,9 +188,13 @@ const generateStyle = (
label: 'heading',
lineHeight: componentTheme.lineHeight,
margin: 0,
display: 'flex',
alignItems: 'center',

//need this for icons to render them vertically centered
...(renderIcon
? {
display: 'flex',
alignItems: 'center'
}
: {}),
// NOTE: the input styles exist to accommodate the InPlaceEdit component
// NOTE: needs separate groups for `:is()` and `:-webkit-any()` because of css selector group validation (see https://www.w3.org/TR/selectors-3/#grouping)
'&:is(input)[type]': inputStyles,
Expand Down
Loading