diff --git a/packages/shared-types/src/BaseTheme.ts b/packages/shared-types/src/BaseTheme.ts
index 26784a7e4e..93d686d31d 100644
--- a/packages/shared-types/src/BaseTheme.ts
+++ b/packages/shared-types/src/BaseTheme.ts
@@ -77,6 +77,35 @@ type Spacing = {
large: string | 0
xLarge: string | 0
xxLarge: string | 0
+
+ space0: string | 0
+ space2: string | 0
+ space4: string | 0
+ space8: string | 0
+ space12: string | 0
+ space16: string | 0
+ space24: string | 0
+ space36: string | 0
+ space48: string | 0
+ space60: string | 0
+ sections: string | 0
+ sectionElements: string | 0
+ trayElements: string | 0
+ modalElements: string | 0
+ moduleElements: string | 0
+ paddingCardLarge: string | 0
+ paddingCardMedium: string | 0
+ paddingCardSmall: string | 0
+ selects: string | 0
+ textareas: string | 0
+ inputFields: string | 0
+ checkboxes: string | 0
+ radios: string | 0
+ toggles: string | 0
+ buttons: string | 0
+ tags: string | 0
+ statusIndicators: string | 0
+ dataPoints: string | 0
}
type Stacking = {
diff --git a/packages/shared-types/src/ComponentThemeVariables.ts b/packages/shared-types/src/ComponentThemeVariables.ts
index bfe9448308..be5c2bed80 100644
--- a/packages/shared-types/src/ComponentThemeVariables.ts
+++ b/packages/shared-types/src/ComponentThemeVariables.ts
@@ -670,6 +670,9 @@ export type ImgTheme = {
export type LinkTheme = {
fontFamily: Typography['fontFamily']
fontWeight: Typography['fontWeightNormal']
+ fontSize: string | 0
+ fontSizeSmall: string | 0
+ lineHeight: number
color: Colors['contrasts']['blue4570']
textDecorationWithinText: string
hoverTextDecorationWithinText: string
@@ -684,7 +687,8 @@ export type LinkTheme = {
focusInverseOutlineColor: Colors['contrasts']['white1010']
focusInverseIconOutlineColor: Colors['contrasts']['white1010']
iconSize: string
- iconPlusTextMargin: Spacing['xxSmall']
+ iconPlusTextMargin: string | 0
+ iconPlusTextMarginSmall: string | 0
textUnderlineOffset: string
}
diff --git a/packages/ui-link/src/Link/README.md b/packages/ui-link/src/Link/README.md
index 37a42470c6..25d0274dbd 100644
--- a/packages/ui-link/src/Link/README.md
+++ b/packages/ui-link/src/Link/README.md
@@ -22,6 +22,37 @@ type: example
```
+### Variant
+
+In order to make it easy to get the most commonly used links, we have the variant prop. It will set all the necessary styles (fontSize, lineHeight, and textDecoration).
+
+```js
+---
+type: example
+---
+
+
+In a line of text you should use the } href="https://instructure.github.io/instructure-ui/">inline link variant.
+
+
+
+
+In a line of text, where the text is smaller, use the } href="https://instructure.github.io/instructure-ui/">inline-small link variant
+
+
+
+
+
+If the link is standalone (not in a text), use the standalone } href="https://instructure.github.io/instructure-ui/">standalone
+
+
+
+
+If the link is standalone (not in a text), but smaller, use the standalone-small } href="https://instructure.github.io/instructure-ui/">standalone-small
+
+
+```
+
### Adding margin
Use the `margin` prop to add space to the left or right of the Link. Because
@@ -76,6 +107,8 @@ Use the `renderIcon` property to put an [icon](#icons) inside a Link. To positio
icon _after_ the link text, change the `iconPlacement` property to `end`. You can also
render a Link with just an icon. Don't forget to add text for screen readers, though.
+NOTE: if you want the icon to have the same `font-size` as the link, do not specify its `size`!
+
```js
---
type: example
diff --git a/packages/ui-link/src/Link/index.tsx b/packages/ui-link/src/Link/index.tsx
index 833afa9723..561907c2b9 100644
--- a/packages/ui-link/src/Link/index.tsx
+++ b/packages/ui-link/src/Link/index.tsx
@@ -252,9 +252,9 @@ class Link extends Component {
tabIndex={tabIndex}
css={this.props.styles?.link}
>
- {renderIcon && iconPlacement === 'start' && this.renderIcon()}
+ {renderIcon && iconPlacement === 'start' ? this.renderIcon() : null}
{children}
- {renderIcon && iconPlacement === 'end' && this.renderIcon()}
+ {renderIcon && iconPlacement === 'end' ? this.renderIcon() : null}
)
}
diff --git a/packages/ui-link/src/Link/props.ts b/packages/ui-link/src/Link/props.ts
index 67b11ef82d..18f21f6e88 100644
--- a/packages/ui-link/src/Link/props.ts
+++ b/packages/ui-link/src/Link/props.ts
@@ -129,6 +129,11 @@ type LinkOwnProps = {
* Fires when the Link is hovered
*/
onMouseEnter?: (event: React.MouseEvent) => void
+
+ /**
+ * Sets pre-defined values for the component to achieve specific roles for the component
+ */
+ variant?: 'inline' | 'inline-small' | 'standalone' | 'standalone-small'
}
export type LinkStyleProps = {
@@ -174,7 +179,13 @@ const propTypes: PropValidators = {
onBlur: PropTypes.func,
onClick: PropTypes.func,
onFocus: PropTypes.func,
- onMouseEnter: PropTypes.func
+ onMouseEnter: PropTypes.func,
+ variant: PropTypes.oneOf([
+ 'inline',
+ 'inline-small',
+ 'standalone',
+ 'standalone-small'
+ ])
}
const allowedProps: AllowedPropKeys = [
@@ -194,7 +205,8 @@ const allowedProps: AllowedPropKeys = [
'onBlur',
'onClick',
'onFocus',
- 'onMouseEnter'
+ 'onMouseEnter',
+ 'variant'
]
export type { LinkProps, LinkState, LinkStyle }
diff --git a/packages/ui-link/src/Link/styles.ts b/packages/ui-link/src/Link/styles.ts
index f67f2d55ed..5c046573c5 100644
--- a/packages/ui-link/src/Link/styles.ts
+++ b/packages/ui-link/src/Link/styles.ts
@@ -40,10 +40,33 @@ const generateStyle = (
props: LinkProps,
state: LinkStyleProps
): LinkStyle => {
- const { isWithinText, renderIcon, iconPlacement, color } = props
+ const { isWithinText, renderIcon, iconPlacement, color, variant } = props
const { containsTruncateText, hasVisibleChildren } = state
const inverseStyle = color === 'link-inverse'
+ const variantStyles = {
+ inline: {
+ fontSize: componentTheme.fontSize,
+ lineHeight: componentTheme.lineHeight,
+ textDecoration: 'underline'
+ },
+ 'inline-small': {
+ fontSize: componentTheme.fontSizeSmall,
+ lineHeight: '1.3125rem',
+ textDecoration: 'underline'
+ },
+ standalone: {
+ fontSize: componentTheme.fontSize,
+ lineHeight: componentTheme.lineHeight,
+ textDecoration: 'none'
+ },
+ 'standalone-small': {
+ fontSize: componentTheme.fontSizeSmall,
+ lineHeight: componentTheme.lineHeight,
+ textDecoration: 'none'
+ }
+ }
+
const baseStyles = {
boxSizing: 'border-box',
fontFamily: componentTheme.fontFamily,
@@ -84,9 +107,6 @@ const generateStyle = (
...baseStyles,
cursor: 'pointer',
color: componentTheme.color,
- textDecoration: isWithinText
- ? componentTheme.textDecorationWithinText
- : componentTheme.textDecorationOutsideText,
'&:focus': {
color: componentTheme.color,
outlineColor: componentTheme.focusOutlineColor
@@ -96,7 +116,14 @@ const generateStyle = (
textDecoration: isWithinText
? componentTheme.hoverTextDecorationWithinText
: componentTheme.hoverTextDecorationOutsideText
- }
+ },
+ ...(variant
+ ? variantStyles[variant]
+ : {
+ textDecoration: isWithinText
+ ? componentTheme.textDecorationWithinText
+ : componentTheme.textDecorationOutsideText
+ })
}
const buttonStyle = {
@@ -105,10 +132,10 @@ const generateStyle = (
background: 'none',
border: 'none',
cursor: 'pointer',
- fontSize: '1em',
margin: 0,
padding: 0,
- textAlign: 'inherit'
+ textAlign: 'inherit',
+ ...(variant ? variantStyles[variant] : { fontSize: '1em' })
}
const inverseStyles = {
@@ -120,7 +147,32 @@ const generateStyle = (
color: componentTheme.colorInverse
}
}
-
+ const variantIconStyles = {
+ inline: {
+ paddingInlineStart:
+ iconPlacement === 'start' ? 0 : componentTheme.iconPlusTextMargin,
+ paddingInlineEnd:
+ iconPlacement === 'start' ? componentTheme.iconPlusTextMargin : 0
+ },
+ 'inline-small': {
+ paddingInlineStart:
+ iconPlacement === 'start' ? 0 : componentTheme.iconPlusTextMarginSmall,
+ paddingInlineEnd:
+ iconPlacement === 'start' ? componentTheme.iconPlusTextMarginSmall : 0
+ },
+ standalone: {
+ paddingInlineStart:
+ iconPlacement === 'start' ? 0 : componentTheme.iconPlusTextMargin,
+ paddingInlineEnd:
+ iconPlacement === 'start' ? componentTheme.iconPlusTextMargin : 0
+ },
+ 'standalone-small': {
+ paddingInlineStart:
+ iconPlacement === 'start' ? 0 : componentTheme.iconPlusTextMarginSmall,
+ paddingInlineEnd:
+ iconPlacement === 'start' ? componentTheme.iconPlusTextMarginSmall : 0
+ }
+ }
return {
link: {
label: 'link',
@@ -145,10 +197,18 @@ const generateStyle = (
...(renderIcon && {
fontSize: componentTheme.iconSize,
boxSizing: 'border-box',
- paddingInlineStart:
- iconPlacement === 'start' ? 0 : componentTheme.iconPlusTextMargin,
- paddingInlineEnd:
- iconPlacement === 'start' ? componentTheme.iconPlusTextMargin : 0
+ ...(variant
+ ? variantIconStyles[variant]
+ : {
+ paddingInlineStart:
+ iconPlacement === 'start'
+ ? 0
+ : componentTheme.iconPlusTextMargin,
+ paddingInlineEnd:
+ iconPlacement === 'start'
+ ? componentTheme.iconPlusTextMargin
+ : 0
+ })
})
}
}
diff --git a/packages/ui-link/src/Link/theme.ts b/packages/ui-link/src/Link/theme.ts
index dfbeb55279..aa576c0cf4 100644
--- a/packages/ui-link/src/Link/theme.ts
+++ b/packages/ui-link/src/Link/theme.ts
@@ -52,6 +52,9 @@ const generateComponentTheme = (theme: Theme): LinkTheme => {
const componentVariables: LinkTheme = {
fontFamily: typography?.fontFamily,
fontWeight: typography?.fontWeightNormal,
+ fontSize: typography?.content,
+ lineHeight: typography?.lineHeight150,
+ fontSizeSmall: typography?.contentSmall,
color: colors?.contrasts?.blue5782,
textDecorationWithinText: 'underline',
@@ -71,7 +74,8 @@ const generateComponentTheme = (theme: Theme): LinkTheme => {
focusInverseIconOutlineColor: colors?.contrasts?.white1010,
iconSize: '1.125em', // make icon slightly larger than inherited font-size,
- iconPlusTextMargin: spacing?.xxSmall,
+ iconPlusTextMargin: spacing.space4,
+ iconPlusTextMarginSmall: spacing.space2,
textUnderlineOffset: 'auto'
}
diff --git a/packages/ui-text/src/Text/index.tsx b/packages/ui-text/src/Text/index.tsx
index c460a6ced1..072d4eba6c 100644
--- a/packages/ui-text/src/Text/index.tsx
+++ b/packages/ui-text/src/Text/index.tsx
@@ -54,11 +54,8 @@ class Text extends Component {
} as const
checkProps() {
- const { variant, size, lineHeight, weight, fontStyle } = this.props
+ const { variant, lineHeight, weight, fontStyle } = this.props
if (variant) {
- if (size) {
- console.warn("[Text]: Don't use 'size' with 'variant' ")
- }
if (lineHeight) {
console.warn("[Text]: Don't use 'lineHeight' with 'variant' ")
}
diff --git a/packages/ui-themes/src/sharedThemeTokens/borders.ts b/packages/ui-themes/src/sharedThemeTokens/borders.ts
index aa0a6e477e..9bb8439b6c 100644
--- a/packages/ui-themes/src/sharedThemeTokens/borders.ts
+++ b/packages/ui-themes/src/sharedThemeTokens/borders.ts
@@ -26,7 +26,7 @@ import { Border } from '@instructure/shared-types'
// use for consistency between buttons, text inputs, etc.
-const borders: Border = Object.freeze({
+const borders: Border = Object.freeze({
radiusSmall: '0.125rem', // 2px
radiusMedium: '0.25rem', // 4px
radiusLarge: '0.5rem', // 8px
diff --git a/packages/ui-themes/src/sharedThemeTokens/breakpoints.ts b/packages/ui-themes/src/sharedThemeTokens/breakpoints.ts
index 58a2bbd457..a27579aae2 100644
--- a/packages/ui-themes/src/sharedThemeTokens/breakpoints.ts
+++ b/packages/ui-themes/src/sharedThemeTokens/breakpoints.ts
@@ -38,7 +38,7 @@ const values = {
xLarge: 75 // 1200px
}
-const breakpoints: Breakpoints = Object.freeze({
+const breakpoints: Breakpoints = Object.freeze({
xxSmall: `${values.xxSmall}em`,
xSmall: `${values.xSmall}em`,
small: `${values.small}em`,
diff --git a/packages/ui-themes/src/sharedThemeTokens/forms.ts b/packages/ui-themes/src/sharedThemeTokens/forms.ts
index a3c3cc3a42..ed5dab7517 100644
--- a/packages/ui-themes/src/sharedThemeTokens/forms.ts
+++ b/packages/ui-themes/src/sharedThemeTokens/forms.ts
@@ -24,7 +24,7 @@
import { Forms } from '@instructure/shared-types'
-const forms: Forms = Object.freeze({
+const forms: Forms = Object.freeze({
inputHeightSmall: '1.75rem',
inputHeightMedium: '2.375rem',
inputHeightLarge: '3rem'
diff --git a/packages/ui-themes/src/sharedThemeTokens/media.ts b/packages/ui-themes/src/sharedThemeTokens/media.ts
index cd29bb3910..dd6ba2cb08 100644
--- a/packages/ui-themes/src/sharedThemeTokens/media.ts
+++ b/packages/ui-themes/src/sharedThemeTokens/media.ts
@@ -25,7 +25,7 @@
import { breakpoints } from './breakpoints'
import { Media } from '@instructure/shared-types'
-const media: Media = Object.freeze({
+const media: Media = Object.freeze({
mediumMin: `min-width: ${breakpoints.medium}`,
largeMin: `min-width: ${breakpoints.large}`,
xLargeMin: `min-width: ${breakpoints.xLarge}`
diff --git a/packages/ui-themes/src/sharedThemeTokens/shadows.ts b/packages/ui-themes/src/sharedThemeTokens/shadows.ts
index 4cfd408e42..4fbe58a722 100644
--- a/packages/ui-themes/src/sharedThemeTokens/shadows.ts
+++ b/packages/ui-themes/src/sharedThemeTokens/shadows.ts
@@ -31,7 +31,7 @@ const values = [
'0 0.375rem 0.4375rem rgba(0, 0, 0, 0.1), 0 0.625rem 1.75rem rgba(0, 0, 0, 0.25)'
]
-const shadows: Shadows = Object.freeze({
+const shadows: Shadows = Object.freeze({
depth1: values[0],
depth2: values[1],
depth3: values[2],
diff --git a/packages/ui-themes/src/sharedThemeTokens/spacing.ts b/packages/ui-themes/src/sharedThemeTokens/spacing.ts
index c51dfdce0b..1c357f3339 100644
--- a/packages/ui-themes/src/sharedThemeTokens/spacing.ts
+++ b/packages/ui-themes/src/sharedThemeTokens/spacing.ts
@@ -24,7 +24,7 @@
import { Spacing } from '@instructure/shared-types'
-const spacing: Spacing = Object.freeze({
+const spacing: Spacing = Object.freeze({
// legacy spacing tokens:
xxxSmall: '0.125rem', // 2px
xxSmall: '0.375rem', // 6px
diff --git a/packages/ui-themes/src/sharedThemeTokens/stacking.ts b/packages/ui-themes/src/sharedThemeTokens/stacking.ts
index a908979fe8..c0f84657cc 100644
--- a/packages/ui-themes/src/sharedThemeTokens/stacking.ts
+++ b/packages/ui-themes/src/sharedThemeTokens/stacking.ts
@@ -24,7 +24,7 @@
import { Stacking } from '@instructure/shared-types'
-const stacking: Stacking = Object.freeze({
+const stacking: Stacking = Object.freeze({
topmost: 9999,
above: 1,
below: -1,
diff --git a/packages/ui-themes/src/sharedThemeTokens/transitions.ts b/packages/ui-themes/src/sharedThemeTokens/transitions.ts
index 98c74ad0c4..1b020249ad 100644
--- a/packages/ui-themes/src/sharedThemeTokens/transitions.ts
+++ b/packages/ui-themes/src/sharedThemeTokens/transitions.ts
@@ -24,7 +24,7 @@
import { Transitions } from '@instructure/shared-types'
-const transitions: Transitions = Object.freeze({
+const transitions: Transitions = Object.freeze({
duration: '300ms',
timing: 'ease-in-out'
} as const)
diff --git a/packages/ui-themes/src/sharedThemeTokens/typography.ts b/packages/ui-themes/src/sharedThemeTokens/typography.ts
index a0f7d8317e..78b3d64186 100644
--- a/packages/ui-themes/src/sharedThemeTokens/typography.ts
+++ b/packages/ui-themes/src/sharedThemeTokens/typography.ts
@@ -24,7 +24,7 @@
import { Typography } from '@instructure/shared-types'
-const typography: Typography = Object.freeze({
+const typography: Typography = Object.freeze({
fontFamily: 'LatoWeb, Lato, "Helvetica Neue", Helvetica, Arial, sans-serif',
fontFamilyMonospace: 'Menlo, Consolas, Monaco, "Andale Mono", monospace',