diff --git a/src/components/Link/Link.stories.mdx b/src/components/Link/Link.stories.mdx new file mode 100644 index 000000000..16278f7eb --- /dev/null +++ b/src/components/Link/Link.stories.mdx @@ -0,0 +1,151 @@ +import { Meta, Preview, Props, Story } from '@storybook/addon-docs'; +import { boolean, select, withKnobs } from '@storybook/addon-knobs'; +import Link from './Link'; +import Stack from '../storyUtils/Stack'; +import { BASE_SHADE } from '../../theme/palette'; +import { FIGMA_URL } from '../../utils/common'; +import { getIconSelectorKnob } from '../../utils/stories'; +import SectionHeader from '../../storybook/SectionHeader'; + + + + + +- [Overview](#overview) +- [Props](#props) +- [Usage](#usage) +- [Variants](#variants) + +## Overview + +A link is a navigational component that takes a user to another URL, an element within the page, or a file. + +## Props + + + +## Usage + + + +To show a primary action (like “Save”), use a Button instead. + +## Props + + + +## Variants + +### Style + + + + + Primary + + + + Inverted + + + + + +### Placement + +Inline: Used within a body of copy; always with underline text decoration for better discoverability
+Block: Used without a body of copy; without underline text decoration + + + + +
+ This is an{' '} + + inline Link + + . +
+
+ This is a + + block Link + + . +
+
+
+
+ +### Sizes + + + + + + Size 1 + + + Size 2 + + + Size 3 + + + + + +### Link with Icon + + + + + + Link + + + Link + + + Link + + + + + +### Playground + + + + + + Link + + + + diff --git a/src/components/Link/Link.style.ts b/src/components/Link/Link.style.ts new file mode 100644 index 000000000..044c321fd --- /dev/null +++ b/src/components/Link/Link.style.ts @@ -0,0 +1,52 @@ +import { css, SerializedStyles } from '@emotion/react'; +import { Theme } from 'theme'; + +import { getLinkTokens, LinkTokens } from './Link.tokens'; +import { LinkProps } from './Link.types'; +import { generateStylesFromTokens } from 'components/Typography/utils'; + +export const linkContainer = + ({ + placement, + type, + size, + isDisabled, + }: Pick) => + (theme: Theme): SerializedStyles => { + const tokens = getLinkTokens(theme); + + return css` + display: ${placement === 'inline' ? 'inline-flex' : 'flex'}; + gap: ${tokens('padding')}; + color: ${tokens(`textColor.${type}.default` as LinkTokens)}; + text-decoration: none; + border: ${tokens('borderWidth.1')} solid ${tokens('borderColor.default')}; + + &:hover { + color: ${tokens(`textColor.${type}.hover` as LinkTokens)}; + path { + fill: ${tokens(`textColor.${type}.hover` as LinkTokens)}; + } + } + + &:visited { + color: ${tokens(`textColor.${type}.visited` as LinkTokens)}; + path { + fill: ${tokens(`textColor.${type}.visited` as LinkTokens)}; + } + } + + &:focus-visible { + border: ${tokens('borderWidth.2')} solid ${tokens('borderColor.focused')}; + } + + opacity: ${isDisabled ? theme.tokens.disabledState.get('default') : 1}; + + width: fit-content; + align-items: center; + cursor: ${isDisabled ? 'default' : 'pointer'}; + pointer-events: ${isDisabled ? 'none' : 'default'}; + + ${generateStylesFromTokens(tokens(`${placement}.${size}` as LinkTokens))} + `; + }; diff --git a/src/components/Link/Link.tokens.ts b/src/components/Link/Link.tokens.ts new file mode 100644 index 000000000..13e00d086 --- /dev/null +++ b/src/components/Link/Link.tokens.ts @@ -0,0 +1,12 @@ +import link from 'theme/tokens/components/variables/link'; +import { getComponentTokens, DotKeys } from 'theme/tokens/utils'; + +import { Theme } from '../../theme'; + +export type LinkTokens = DotKeys; + +export const getLinkTokens = ( + theme: Theme +): ((path: LinkTokens, fn?: (val: string) => any) => any) => { + return getComponentTokens(link, theme); +}; diff --git a/src/components/Link/Link.tsx b/src/components/Link/Link.tsx new file mode 100644 index 000000000..a2d4e25cf --- /dev/null +++ b/src/components/Link/Link.tsx @@ -0,0 +1,51 @@ +import useTheme from 'hooks/useTheme'; +import React, { AnchorHTMLAttributes } from 'react'; + +import { linkContainer } from './Link.style'; +import { LinkTokens, getLinkTokens } from './Link.tokens'; +import { LinkProps } from './Link.types'; +import Icon from 'components/Icon'; + +const Link = React.forwardRef< + HTMLAnchorElement, + AnchorHTMLAttributes & LinkProps +>((props, ref) => { + const { + type = 'primary', + placement = 'block', + size = 1, + iconName, + isDisabled, + dataTestPrefixId = '', + children, + ...rest + } = props; + + const theme = useTheme(); + + const tokens = getLinkTokens(theme); + + return ( + + {children} + {/** @TODO Set the right size for the icon based on tokens once Icon component is refactored */} + {iconName && ( + + )} + + ); +}); + +Link.displayName = 'Link'; + +export default Link; diff --git a/src/components/Link/Link.types.ts b/src/components/Link/Link.types.ts new file mode 100644 index 000000000..e4e174c94 --- /dev/null +++ b/src/components/Link/Link.types.ts @@ -0,0 +1,18 @@ +import { AcceptedIconNames } from 'components/Icon'; + +type LinkSizes = 1 | 2 | 3; + +export type LinkProps = { + /** The type of the Link in terms of style */ + type?: 'primary' | 'inverted'; + /** The placement of the link */ + placement?: 'block' | 'inline'; + /** The size of the Link */ + size?: LinkSizes; + /** Optional icon to add at the right of the Link */ + iconName?: AcceptedIconNames; + /** Whether the link is disabled*/ + isDisabled?: boolean; + /** Data Test Id prefix **/ + dataTestPrefixId?: string; +}; diff --git a/src/components/Link/__snapshots__/Link.stories.storyshot b/src/components/Link/__snapshots__/Link.stories.storyshot new file mode 100644 index 000000000..1556ee1e1 --- /dev/null +++ b/src/components/Link/__snapshots__/Link.stories.storyshot @@ -0,0 +1,1008 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Storyshots Design System/Link Link with Icon 1`] = ` +.emotion-0 { + -webkit-flex-direction: column; + -ms-flex-direction: column; + flex-direction: column; + -webkit-flex: 1; + -ms-flex: 1; + flex: 1; + position: relative; + padding: 0.25rem; +} + +.emotion-1 { + margin: 1rem; +} + +.emotion-2 { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-flex-direction: column; + -ms-flex-direction: column; + flex-direction: column; + -webkit-box-flex-wrap: wrap; + -webkit-flex-wrap: wrap; + -ms-flex-wrap: wrap; + flex-wrap: wrap; +} + +.emotion-3 { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + gap: 0.25rem; + color: #1552DD; + -webkit-text-decoration: none; + text-decoration: none; + border: 0.25rem solid rgba(84,94,255,0); + opacity: 1; + width: -webkit-fit-content; + width: -moz-fit-content; + width: fit-content; + -webkit-align-items: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + cursor: pointer; + pointer-events: default; + font-family: Roboto; + font-weight: 500; + line-height: 1.375rem; + font-size: 1rem; + letter-spacing: 0.00625rem; +} + +.emotion-3:hover { + color: #1B214F; +} + +.emotion-3:hover path { + fill: #1B214F; +} + +.emotion-3:visited { + color: #6c28cc; +} + +.emotion-3:visited path { + fill: #6c28cc; +} + +.emotion-3:focus-visible { + border: 0.25rem solid #9347ff; +} + +.emotion-4 { + padding: 0.125rem; + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-align-items: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -ms-flex-pack: center; + -webkit-justify-content: center; + justify-content: center; +} + +.emotion-5 { + fill: #1552DD; + width: 0.75rem; + height: 0.75rem; +} + +.emotion-5 path { + fill: #1552DD; +} + +.emotion-6 { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + gap: 0.25rem; + color: #1552DD; + -webkit-text-decoration: none; + text-decoration: none; + border: 0.25rem solid rgba(84,94,255,0); + opacity: 1; + width: -webkit-fit-content; + width: -moz-fit-content; + width: fit-content; + -webkit-align-items: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + cursor: pointer; + pointer-events: default; + font-family: Roboto; + font-weight: 500; + line-height: 1.25rem; + font-size: 0.875rem; + letter-spacing: 0.015625rem; +} + +.emotion-6:hover { + color: #1B214F; +} + +.emotion-6:hover path { + fill: #1B214F; +} + +.emotion-6:visited { + color: #6c28cc; +} + +.emotion-6:visited path { + fill: #6c28cc; +} + +.emotion-6:focus-visible { + border: 0.25rem solid #9347ff; +} + +.emotion-9 { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + gap: 0.25rem; + color: #1552DD; + -webkit-text-decoration: none; + text-decoration: none; + border: 0.25rem solid rgba(84,94,255,0); + opacity: 1; + width: -webkit-fit-content; + width: -moz-fit-content; + width: fit-content; + -webkit-align-items: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + cursor: pointer; + pointer-events: default; + font-family: Roboto; + font-weight: 500; + line-height: 1rem; + font-size: 0.75rem; + letter-spacing: 0.015625rem; +} + +.emotion-9:hover { + color: #1B214F; +} + +.emotion-9:hover path { + fill: #1B214F; +} + +.emotion-9:visited { + color: #6c28cc; +} + +.emotion-9:visited path { + fill: #6c28cc; +} + +.emotion-9:focus-visible { + border: 0.25rem solid #9347ff; +} + + +`; + +exports[`Storyshots Design System/Link Placement 1`] = ` +.emotion-0 { + -webkit-flex-direction: column; + -ms-flex-direction: column; + flex-direction: column; + -webkit-flex: 1; + -ms-flex: 1; + flex: 1; + position: relative; + padding: 0.25rem; +} + +.emotion-1 { + margin: 1rem; +} + +.emotion-2 { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-flex-direction: column; + -ms-flex-direction: column; + flex-direction: column; + -webkit-box-flex-wrap: wrap; + -webkit-flex-wrap: wrap; + -ms-flex-wrap: wrap; + flex-wrap: wrap; +} + +.emotion-3 { + display: -webkit-inline-box; + display: -webkit-inline-flex; + display: -ms-inline-flexbox; + display: inline-flex; + gap: 0.25rem; + color: #1552DD; + -webkit-text-decoration: none; + text-decoration: none; + border: 0.25rem solid rgba(84,94,255,0); + opacity: 1; + width: -webkit-fit-content; + width: -moz-fit-content; + width: fit-content; + -webkit-align-items: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + cursor: pointer; + pointer-events: default; + font-family: Roboto; + font-weight: 500; + line-height: 1.375rem; + font-size: 1rem; + letter-spacing: 0.00625rem; + -webkit-text-decoration: underline; + text-decoration: underline; +} + +.emotion-3:hover { + color: #1B214F; +} + +.emotion-3:hover path { + fill: #1B214F; +} + +.emotion-3:visited { + color: #6c28cc; +} + +.emotion-3:visited path { + fill: #6c28cc; +} + +.emotion-3:focus-visible { + border: 0.25rem solid #9347ff; +} + +.emotion-4 { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + gap: 0.25rem; + color: #1552DD; + -webkit-text-decoration: none; + text-decoration: none; + border: 0.25rem solid rgba(84,94,255,0); + opacity: 1; + width: -webkit-fit-content; + width: -moz-fit-content; + width: fit-content; + -webkit-align-items: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + cursor: pointer; + pointer-events: default; + font-family: Roboto; + font-weight: 500; + line-height: 1.375rem; + font-size: 1rem; + letter-spacing: 0.00625rem; +} + +.emotion-4:hover { + color: #1B214F; +} + +.emotion-4:hover path { + fill: #1B214F; +} + +.emotion-4:visited { + color: #6c28cc; +} + +.emotion-4:visited path { + fill: #6c28cc; +} + +.emotion-4:focus-visible { + border: 0.25rem solid #9347ff; +} + +
+
+
+
+
+ This is an + + + + inline Link + + + . +
+
+
+
+ This is a + + + block Link + + + . +
+
+
+
+
+`; + +exports[`Storyshots Design System/Link Playground 1`] = ` +.emotion-0 { + -webkit-flex-direction: column; + -ms-flex-direction: column; + flex-direction: column; + -webkit-flex: 1; + -ms-flex: 1; + flex: 1; + position: relative; + padding: 0.25rem; +} + +.emotion-1 { + margin: 1rem; +} + +.emotion-2 { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-flex-direction: column; + -ms-flex-direction: column; + flex-direction: column; + -webkit-box-flex-wrap: wrap; + -webkit-flex-wrap: wrap; + -ms-flex-wrap: wrap; + flex-wrap: wrap; +} + +.emotion-3 { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + gap: 0.25rem; + color: #1552DD; + -webkit-text-decoration: none; + text-decoration: none; + border: 0.25rem solid rgba(84,94,255,0); + opacity: 1; + width: -webkit-fit-content; + width: -moz-fit-content; + width: fit-content; + -webkit-align-items: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + cursor: pointer; + pointer-events: default; + font-family: Roboto; + font-weight: 500; + line-height: 1.375rem; + font-size: 1rem; + letter-spacing: 0.00625rem; +} + +.emotion-3:hover { + color: #1B214F; +} + +.emotion-3:hover path { + fill: #1B214F; +} + +.emotion-3:visited { + color: #6c28cc; +} + +.emotion-3:visited path { + fill: #6c28cc; +} + +.emotion-3:focus-visible { + border: 0.25rem solid #9347ff; +} + +
+
+ +
+
+`; + +exports[`Storyshots Design System/Link Sizes 1`] = ` +.emotion-0 { + -webkit-flex-direction: column; + -ms-flex-direction: column; + flex-direction: column; + -webkit-flex: 1; + -ms-flex: 1; + flex: 1; + position: relative; + padding: 0.25rem; +} + +.emotion-1 { + margin: 1rem; +} + +.emotion-2 { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-flex-direction: column; + -ms-flex-direction: column; + flex-direction: column; + -webkit-box-flex-wrap: wrap; + -webkit-flex-wrap: wrap; + -ms-flex-wrap: wrap; + flex-wrap: wrap; +} + +.emotion-3 { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + gap: 0.25rem; + color: #1552DD; + -webkit-text-decoration: none; + text-decoration: none; + border: 0.25rem solid rgba(84,94,255,0); + opacity: 1; + width: -webkit-fit-content; + width: -moz-fit-content; + width: fit-content; + -webkit-align-items: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + cursor: pointer; + pointer-events: default; + font-family: Roboto; + font-weight: 500; + line-height: 1.375rem; + font-size: 1rem; + letter-spacing: 0.00625rem; +} + +.emotion-3:hover { + color: #1B214F; +} + +.emotion-3:hover path { + fill: #1B214F; +} + +.emotion-3:visited { + color: #6c28cc; +} + +.emotion-3:visited path { + fill: #6c28cc; +} + +.emotion-3:focus-visible { + border: 0.25rem solid #9347ff; +} + +.emotion-4 { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + gap: 0.25rem; + color: #1552DD; + -webkit-text-decoration: none; + text-decoration: none; + border: 0.25rem solid rgba(84,94,255,0); + opacity: 1; + width: -webkit-fit-content; + width: -moz-fit-content; + width: fit-content; + -webkit-align-items: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + cursor: pointer; + pointer-events: default; + font-family: Roboto; + font-weight: 500; + line-height: 1.25rem; + font-size: 0.875rem; + letter-spacing: 0.015625rem; +} + +.emotion-4:hover { + color: #1B214F; +} + +.emotion-4:hover path { + fill: #1B214F; +} + +.emotion-4:visited { + color: #6c28cc; +} + +.emotion-4:visited path { + fill: #6c28cc; +} + +.emotion-4:focus-visible { + border: 0.25rem solid #9347ff; +} + +.emotion-5 { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + gap: 0.25rem; + color: #1552DD; + -webkit-text-decoration: none; + text-decoration: none; + border: 0.25rem solid rgba(84,94,255,0); + opacity: 1; + width: -webkit-fit-content; + width: -moz-fit-content; + width: fit-content; + -webkit-align-items: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + cursor: pointer; + pointer-events: default; + font-family: Roboto; + font-weight: 500; + line-height: 1rem; + font-size: 0.75rem; + letter-spacing: 0.015625rem; +} + +.emotion-5:hover { + color: #1B214F; +} + +.emotion-5:hover path { + fill: #1B214F; +} + +.emotion-5:visited { + color: #6c28cc; +} + +.emotion-5:visited path { + fill: #6c28cc; +} + +.emotion-5:focus-visible { + border: 0.25rem solid #9347ff; +} + + +`; + +exports[`Storyshots Design System/Link Style 1`] = ` +.emotion-0 { + -webkit-flex-direction: column; + -ms-flex-direction: column; + flex-direction: column; + -webkit-flex: 1; + -ms-flex: 1; + flex: 1; + position: relative; + padding: 0.25rem; +} + +.emotion-1 { + margin: 1rem; +} + +.emotion-2 { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-flex-direction: column; + -ms-flex-direction: column; + flex-direction: column; + -webkit-box-flex-wrap: wrap; + -webkit-flex-wrap: wrap; + -ms-flex-wrap: wrap; + flex-wrap: wrap; +} + +.emotion-3 { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + gap: 0.25rem; + color: #1552DD; + -webkit-text-decoration: none; + text-decoration: none; + border: 0.25rem solid rgba(84,94,255,0); + opacity: 1; + width: -webkit-fit-content; + width: -moz-fit-content; + width: fit-content; + -webkit-align-items: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + cursor: pointer; + pointer-events: default; + font-family: Roboto; + font-weight: 500; + line-height: 1.375rem; + font-size: 1rem; + letter-spacing: 0.00625rem; +} + +.emotion-3:hover { + color: #1B214F; +} + +.emotion-3:hover path { + fill: #1B214F; +} + +.emotion-3:visited { + color: #6c28cc; +} + +.emotion-3:visited path { + fill: #6c28cc; +} + +.emotion-3:focus-visible { + border: 0.25rem solid #9347ff; +} + +.emotion-4 { + background: #1B214F; + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-flex-direction: row; + -ms-flex-direction: row; + flex-direction: row; + -webkit-box-flex-wrap: wrap; + -webkit-flex-wrap: wrap; + -ms-flex-wrap: wrap; + flex-wrap: wrap; +} + +.emotion-5 { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + gap: 0.25rem; + color: #1de9b6; + -webkit-text-decoration: none; + text-decoration: none; + border: 0.25rem solid rgba(84,94,255,0); + opacity: 1; + width: -webkit-fit-content; + width: -moz-fit-content; + width: fit-content; + -webkit-align-items: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + cursor: pointer; + pointer-events: default; + font-family: Roboto; + font-weight: 500; + line-height: 1.375rem; + font-size: 1rem; + letter-spacing: 0.00625rem; +} + +.emotion-5:hover { + color: #ffffff; +} + +.emotion-5:hover path { + fill: #ffffff; +} + +.emotion-5:visited { + color: #dbc1ff; +} + +.emotion-5:visited path { + fill: #dbc1ff; +} + +.emotion-5:focus-visible { + border: 0.25rem solid #9347ff; +} + +
+ +
+`; diff --git a/src/components/Link/index.ts b/src/components/Link/index.ts new file mode 100644 index 000000000..241046084 --- /dev/null +++ b/src/components/Link/index.ts @@ -0,0 +1 @@ +export { default } from './Link'; diff --git a/src/index.ts b/src/index.ts index eba271b4a..f88d1461c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -47,6 +47,8 @@ export { default as ExpandCollapse } from './components/ExpandCollapse'; export * from './components/ExpandCollapse'; export { default as Icon } from './components/Icon'; export * from './components/Icon'; +export { default as Link } from './components/Link'; +export * from './components/Link'; export { default as IconButton } from './components/IconButton'; export * from './components/IconButton'; export { default as Label } from './components/Label'; diff --git a/src/theme/tokens/components/variables/link.ts b/src/theme/tokens/components/variables/link.ts new file mode 100644 index 000000000..361fee455 --- /dev/null +++ b/src/theme/tokens/components/variables/link.ts @@ -0,0 +1,132 @@ +const link = { + padding: { + value: '{spacing.3}', + type: 'spacing', + description: 'Sets padding between a link and a link icon', + }, + textColor: { + primary: { + default: { + value: '{sem.colors.textColor.default.active}', + type: 'color', + description: 'Sets text color for primary default link', + }, + hover: { + value: '{sem.colors.textColor.default.primary}', + type: 'color', + description: 'Sets text color for a primary hovered link', + }, + visited: { + value: '{sem.colors.textColor.default.visited}', + type: 'color', + description: 'Sets text color for a primary visited link', + }, + }, + inverted: { + default: { + value: '{sem.colors.textColor.inverted.active}', + type: 'color', + description: 'Sets text color for inverted default link', + }, + hover: { + value: '{sem.colors.textColor.inverted.primary}', + type: 'color', + description: 'Sets text color for a primary hovered link', + }, + visited: { + value: '{sem.colors.textColor.inverted.visited}', + type: 'color', + description: 'Sets text color for a primary visited link', + }, + }, + }, + borderColor: { + focused: { + value: '{sem.colors.borderColor.interactive.focused}', + type: 'color', + description: 'Sets borderColor for focused link state', + }, + default: { + value: '{sem.colors.borderColor.decorative.transparent}', + type: 'color', + description: 'Sets borderColor for all link states except for focused', + }, + }, + block: { + '1': { + value: '{sem.typography.normal.label01}', + type: 'typography', + description: 'Sets text for large default standalone link', + }, + '2': { + value: '{sem.typography.normal.label02}', + type: 'typography', + description: 'Sets text for medium default standalone link', + }, + '3': { + value: '{sem.typography.normal.label03}', + type: 'typography', + description: 'Sets text for small default standalone link', + }, + }, + inline: { + '1': { + value: { + fontFamily: '{fontFamily.roboto}', + fontWeight: '{fontWeight.medium}', + lineHeight: '{lineHeight.5}', + fontSize: '{fontSize.4}', + letterSpacing: '{letterSpacing.1}', + textDecoration: '{textDecoration.link}', + }, + type: 'typography', + description: + 'Sets text for a large inline link and all large standalone link states (except for default)', + }, + '2': { + value: { + fontFamily: '{fontFamily.roboto}', + fontWeight: '{fontWeight.medium}', + lineHeight: '{lineHeight.4}', + fontSize: '{fontSize.3}', + letterSpacing: '{letterSpacing.2}', + textDecoration: '{textDecoration.link}', + }, + type: 'typography', + description: + 'Sets text for a medium inline link and all large standalone link states (except for default)', + }, + '3': { + value: { + fontFamily: '{fontFamily.roboto}', + fontWeight: '{fontWeight.medium}', + lineHeight: '{lineHeight.3}', + fontSize: '{fontSize.2}', + letterSpacing: '{letterSpacing.2}', + textDecoration: '{textDecoration.link}', + }, + type: 'typography', + description: + 'Sets text for a small inline link and all large standalone link states (except for default)', + }, + }, + borderWidth: { + '1': { + value: '{borderWidth.3}', + type: 'borderWidth', + description: 'Sets border width for all link states apart from focused', + }, + '2': { + value: '{borderWidth.3}', + type: 'borderWidth', + description: 'Sets border width for focused state', + }, + }, + iconSize: { + value: '{sem.icon.size.1}', + type: 'sizing', + description: 'Sets size for optional link icon', + }, +} as const; + +export default link; diff --git a/src/utils/stories.ts b/src/utils/stories.ts index 6f7d14595..4ad0a538b 100644 --- a/src/utils/stories.ts +++ b/src/utils/stories.ts @@ -1,12 +1,13 @@ import { select } from '@storybook/addon-knobs'; +import { AcceptedIconNames } from 'components/Icon'; import iconSelector from 'components/Icon/assets/iconSelector'; -export const getIconSelectorKnob = (propName: string) => +export const getIconSelectorKnob = (propName: string, initialValue?: AcceptedIconNames) => select( propName, Object.keys(iconSelector) .sort((a, b) => a.localeCompare(b)) .map((iconName) => iconName), - 'check' + initialValue ?? 'check' );