From 29ea1e48cd290ce5efc360029b3e432d3ee90b52 Mon Sep 17 00:00:00 2001 From: irmir Date: Wed, 25 Aug 2021 18:12:36 +0300 Subject: [PATCH] docs: create stories for UI Helpers Create ThemeProvider, Theme, Utils, Typography, Link stories closes #46 --- packages/theme/package.json | 5 + packages/theme/src/Theme.stories.tsx | 298 ++++++++++++++++++ packages/theme/src/ThemeProvider.stories.tsx | 294 +++++++++++++++++ packages/typography/package.json | 5 + packages/typography/src/Link.stories.tsx | 50 +++ .../typography/src/Typography.stories.tsx | 102 ++++++ packages/utils/package.json | 5 + packages/utils/src/Utils.stories.tsx | 298 ++++++++++++++++++ packages/utils/src/storyTemplate.tsx | 132 ++++++++ 9 files changed, 1189 insertions(+) create mode 100644 packages/theme/src/Theme.stories.tsx create mode 100644 packages/theme/src/ThemeProvider.stories.tsx create mode 100644 packages/typography/src/Link.stories.tsx create mode 100644 packages/typography/src/Typography.stories.tsx create mode 100644 packages/utils/src/Utils.stories.tsx create mode 100644 packages/utils/src/storyTemplate.tsx diff --git a/packages/theme/package.json b/packages/theme/package.json index 1a5eb3cb3..ace1375a9 100644 --- a/packages/theme/package.json +++ b/packages/theme/package.json @@ -28,6 +28,11 @@ "react": ">=16.8.0 <18", "react-dom": ">=16.2.0 <18" }, + "devDependencies": { + "@atlaskit/code": "14.1.3", + "@storybook/react": "6.4.10", + "styled-components": "5.3.1" + }, "publishConfig": { "access": "public" }, diff --git a/packages/theme/src/Theme.stories.tsx b/packages/theme/src/Theme.stories.tsx new file mode 100644 index 000000000..082b4dbea --- /dev/null +++ b/packages/theme/src/Theme.stories.tsx @@ -0,0 +1,298 @@ +import { ThemeProvider as EmotionThemeProvider } from '@emotion/react'; +import styled from '@emotion/styled'; +import { Story, Meta } from '@storybook/react'; +import { useState, useEffect } from 'react'; + +import { Typography } from '../../typography'; + +import { Spacing, DEPTH } from './Theme'; +import { ThemeProvider } from './ThemeProvider'; +import { Wrapper } from './ThemeProvider.stories'; +import { FontWeight } from './fonts/weights'; +import { useColor } from './hooks'; + +import { COLORS, CLASSIC_COLORS } from './index'; + +export default { + title: 'UI Helpers/Theme', + parameters: { + layout: 'fullscreen', + controls: { + exclude: ['data-testid'] + } + } +} as Meta; + +const Table = styled.table` + margin-top: 0px; + border-collapse: collapse; + color: #767676; + font-size: 15px; + font-family: 'IBM Plex Sans', sans-serif; + color: rgb(51, 51, 51); + margin-bottom: 20px; + th { + font-weight: bold; + text-align: start; + border-bottom: 1px solid rgb(232, 232, 232); + } + td { + padding: 4px 16px 4px 0px; + line-height: 1.5; + span { + line-height: 1; + margin: 0 2px; + padding: 2px 4px; + white-space: nowrap; + border-radius: 3px; + font-size: 13px; + border: 1px solid #eeeeee; + color: rgba(51, 51, 51, 0.9); + background-color: #f8f8f8; + } + } +`; + +const Heading = styled.h4` + ${Typography.Heading4}; + padding: 10px 0; +`; + +const InfoTemplate = () => ( + + Available Values + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
export nameusage
FieldHeight + enum of standard field heights in px, eg <input> +
Spacingenum of standard spacing size in px
Sizeenum used for referencing standard sizing options
ZIndexenum used for separating different z-index usages
BORDER_RADIUSStandard border-radius size (number)
DEPTHlist of box-shadow and borders for simulating depth
COLORS + default base color palette, usage is COLORS.RED.L2 +
CLASSIC_COLORS + classic theme color palette, should be put inserted in the theme + object{' '} +
DARK_COLORS + dark mode theme color palette, should be inserted in the theme + object{' '} +
getCdnPath + returns a url for the desired font on our tablecheck CDN,{' '} + cdnUrl must be defined in the node-config{' '} +
+ Available Types + + + + + + + + + + + + + + + + + +
export nameusage
Level + enum used for type checking L1 - L9 key values, usually just COLOR + keys +
LevelConst<T> + object type that requires keys L1 - L9 to be defined, `T` is the + value type +
+
+); + +export const Information = InfoTemplate.bind({}); + +const SpacingTemplate = () => ( + +

+ Standard spacing set is defined in Spacing object. +

+ {Object.keys(Spacing).map((space) => { + const StyledDiv = styled.div` + background: #c7b6f1; + width: ${Spacing[space as keyof typeof Spacing]}; + height: 20px; + margin-bottom: 10px; + margin-right: 10px; + `; + const Flex = styled.div` + display: flex; + `; + const Label = styled.div` + width: '90px'; + `; + + return ( + + + + + + ); + })} +
+); + +export const Spaces = SpacingTemplate.bind({}); + +const DepthRow = styled.div` + display: flex; + padding: 24px; + background-color: ${COLORS.GRAY.L1}; + justify-content: space-between; +`; + +const DepthItem = styled.div<{ depth: { boxShadow: string } }>` + width: 20%; + height: 120px; + display: flex; + justify-content: center; + align-items: center; + ${({ depth }) => `box-shadow: ${depth.boxShadow}`}; +`; + +const DepthTemplate = () => ( + + + {Object.keys(DEPTH).map((key) => ( + + {key} + + ))} + + +); + +export const Depth = DepthTemplate.bind({}); + +const Text = styled.p<{ weight: number }>` + ${({ weight }) => `font-weight: ${weight}`} +`; + +const FontWeightTemplate: Story = () => ( + +

+ The following font-weights are also exported as helpers to go along with + the font-face definitions that get inserted from{' '} + ThemeProvider +

+ {[ + FontWeight.ExtraLight, + FontWeight.Light, + FontWeight.Regular, + FontWeight.Medium, + FontWeight.SemiBold, + FontWeight.Bold + ].map((key) => ( + + FontWeight.{FontWeight[key]} ({key}) + + ))} +
+); + +export const FontWeightExample = FontWeightTemplate.bind({}); +FontWeightExample.storyName = 'Font Weight'; + +const colorKey = 'primary'; + +const Div = styled.div` + align-items: center; + background-color: #c7b6f1; + display: flex; + justify-content: center; + flex-direction: column; + min-height: 76px; + margin: 20px auto; + width: 400px; + padding: ${Spacing.L2}; + text-align: center; + ${({ color }) => `color: ${color}`} +`; + +const Example = () => { + const color = useColor(colorKey); + return
Use hooks to get a value ...
; +}; + +const ThemeHooksTemplate = () => { + const [presenterTheme, setTheme] = useState({ + colors: { + ...CLASSIC_COLORS + } + }); + useEffect(() => { + const colors = Object.values(CLASSIC_COLORS); + const intervalId = setInterval(() => { + const colorIndex = Math.floor(Math.random() * colors.length); + setTheme((state) => ({ + colors: { + ...state.colors, + [colorKey]: colors[colorIndex] + } + })); + }, 1000); + return () => clearInterval(intervalId); + }, [setTheme]); + return ( + + + + + + ); +}; + +export const ThemeHooks = ThemeHooksTemplate.bind({}); diff --git a/packages/theme/src/ThemeProvider.stories.tsx b/packages/theme/src/ThemeProvider.stories.tsx new file mode 100644 index 000000000..708628bc4 --- /dev/null +++ b/packages/theme/src/ThemeProvider.stories.tsx @@ -0,0 +1,294 @@ +import { CodeBlock } from '@atlaskit/code'; +import { useTheme, Global, css } from '@emotion/react'; +import styled from '@emotion/styled'; +import { Meta } from '@storybook/react'; +import { ifRtl } from '@tablecheck/tablekit-utils'; +import { useState } from 'react'; + +import { Button, ButtonAppearance } from '../../button'; +import { Toggle } from '../../toggle'; +import { Link, Typography } from '../../typography'; + +import { DARK_COLORS } from './palettes'; + +import { ThemeProvider } from './index'; + +export default { + title: 'UI Helpers/ThemeProvider', + component: ThemeProvider, + parameters: { + controls: { + exclude: ['data-testid'] + } + }, + excludeStories: ['Wrapper'] +} as Meta; + +export const Wrapper = styled.div` + ${Typography.Body1}; + margin: 20px auto 0; + display: flex; + flex-direction: column; + width: 94% !important; + p, + ul li { + padding: 10px 0; + span { + line-height: 1; + margin: 0 2px; + padding: 2px 4px; + white-space: nowrap; + border-radius: 3px; + font-size: 13px; + border: 1px solid #eeeeee; + color: rgba(51, 51, 51, 0.9); + background-color: #f8f8f8; + } + } + ul { + list-style: disc; + padding-left: 20px; + li { + padding-bottom: 10px; + } + } + label { + display: flex; + justify-content: center; + padding-top: 15px; + } + button { + margin-right: 10px; + } +`; + +const Heading = styled.h4` + ${Typography.Heading4}; + padding: 10px 0; +`; + +const themeProviderCode = ` +import ThemeProvider from '@tablekit/theme/ThemeProvider'; +import {useTheme} from 'emotion-theming'; + + + //Children with context available + {useTheme().isRtl === false} +; +`; + +const ThemeProviderCodeBlock = ({ children }: { children: JSX.Element }) => ( +
{children}
+); + +const InfoTemplate = () => ( + +

+ Formerly ResetStyles +

+

+ This component sets up the correct css and theme variables to + "reset" the browsers CSS to the correct base for TableKit + applications. +

+

+ Via ThemeProvider + An important part of this is the correct setting of fonts and sizing per + language and providing a consistent way of resetting this value via + emotions ThemeProvider. +

+

+ The country and locale props are used to correctly set the font-family and + load the correct font-face settings. By default only FontWeight.Regular + and FontWeight.Bold are preloaded if your app needs more fonts than this + at the start use the fontWeights prop and pass in all the + font weights your app needs. The other font weights are also defined, but + the font will not be loaded for that font-weight until it is used. This{' '} + font-family value is also available via a Context. This also + adds the isRtl flag to the theme based on matching{' '} + locale prop to @tablecheck/locales. +

+

+ The isDark prop is used to indicate the components within the + ThemeProvider that the current theme has dark tones. This is useful to + know in certain situations that colors need to be inverted. +

+

+ The context value is useful for cases when you are also using custom + Header fonts, for example the Poppins Header styles from + @tablecheck/tablekit-typography. +

+ + + +
+); + +export const Information = InfoTemplate.bind({}); + +const DirSpan = styled.div` + padding: 12px; + ${({ theme }) => + `background-color: ${theme.colors.canvas}; color: ${theme.colors.text};`}; + ${(props) => ({ textAlign: ifRtl('right', 'left')(props) })}; +`; + +const ThemeTest = () => ( +
+ {useTheme().isRtl ? rtl : ltr} + {useTheme().fontFamily} +
+); + +const Template = () => { + const [locale, setLocale] = useState('ja'); + return ( + + +
+ + + +
+
+ Theme Test with Classic Mode +
+ + + + + Theme Test with Dark Mode + +
+
+ ); +}; + +export const Examples = Template.bind({}); + +const firstCodeBlock = ` +variables: + APP_VERSION: '\${CI_COMMIT_REF_NAME}' +`; + +const secondCodeBlock = ` +{ + "appVersion": "development" +} +`; + +const thirdCodeBlock = ` +{ + "appVersion": "APP_VERSION" +} +`; + +const CDHelperTemplate = () => { + const [isDisplayed, setIsDisplayed] = useState(false); + return ( + +

+ As part of the ThemeProvider we include a way of rendering the current + CI branch/tag value as passed through from the CI. By default this tag + is hidden but can be toggled with the{' '} + + TableKit chrome browser plugin + +

+

+ To enable this in a project the following extra steps need to be + undertaken. +

+ + + { + setIsDisplayed(!isDisplayed); + }} + /> + + +
+ ); +}; + +export const CDHelper = CDHelperTemplate.bind({}); diff --git a/packages/typography/package.json b/packages/typography/package.json index 3a544b408..2d347125d 100644 --- a/packages/typography/package.json +++ b/packages/typography/package.json @@ -27,6 +27,11 @@ "react": ">=16.8.0 <18", "react-dom": ">=16.2.0 <18" }, + "devDependencies": { + "@atlaskit/code": "14.1.3", + "@storybook/react": "6.4.10", + "styled-components": "5.3.1" + }, "publishConfig": { "access": "public" }, diff --git a/packages/typography/src/Link.stories.tsx b/packages/typography/src/Link.stories.tsx new file mode 100644 index 000000000..770849d19 --- /dev/null +++ b/packages/typography/src/Link.stories.tsx @@ -0,0 +1,50 @@ +import { CodeBlock } from '@atlaskit/code'; +import styled from '@emotion/styled'; +import { Meta, Story } from '@storybook/react'; + +import { Typography } from '..'; + +import { Link } from './Link'; + +export default { + title: 'Type System/Link', + parameters: { + layout: 'fullscreen' + } +} as Meta; + +const Wrapper = styled.div` + ${Typography.Body1}; + margin: 20px auto 0; + display: flex; + flex-direction: column; + width: 94% !important; +`; + +const linkCode = ` +import { Link } from './Link'; +import { ThemeProvider } from '@tablecheck/tablekit-theme'; + + + Here is a link on it's own +; +`; + +const TypographyCodeBlock = ({ children }: { children: JSX.Element }) => ( +
{children}
+); + +const Template: Story = () => ( + +
+ Here is a link on it is own +
+
+ + + +
+); + +export const LinkExample = Template.bind({}); +LinkExample.storyName = 'Link'; diff --git a/packages/typography/src/Typography.stories.tsx b/packages/typography/src/Typography.stories.tsx new file mode 100644 index 000000000..cde284185 --- /dev/null +++ b/packages/typography/src/Typography.stories.tsx @@ -0,0 +1,102 @@ +import { CodeBlock } from '@atlaskit/code'; +import styled from '@emotion/styled'; +import { Meta, Story } from '@storybook/react'; + +import { Typography } from '..'; + +export default { + title: 'Type System/Typography', + parameters: { + layout: 'fullscreen' + }, + excludeStories: ['Wrapper', 'UtilsCodeBlock', 'Heading'] +} as Meta; + +const Wrapper = styled.div` + ${Typography.Body1}; + margin: 20px auto 0; + display: flex; + flex-direction: column; + width: 94% !important; + p, + ul li { + padding: 10px 0; + span { + line-height: 1; + margin: 0 2px; + padding: 2px 4px; + white-space: nowrap; + border-radius: 3px; + font-size: 13px; + border: 1px solid #eeeeee; + color: rgba(51, 51, 51, 0.9); + background-color: #f8f8f8; + } + } +`; + +const typographyCode1 = ` +import { Global, css } from '@emotion/react'; +import { + desktopTypographyStyles, + mobileTypographyStyles, + commonTypographyStyles +} from '@tablecheck/tablekit-typography'; + +; +`; + +const typographyCode2 = ` +import { + TypographyHeadlineDesktop, + TypographyHeadlineMobile +} from '@tablecheck/tablekit-typography'; + +const CustomDesktopHeadline = styled.h1\` + \${TypographyHeadlineDesktop.Headline}; +\`; + +const CustomMobileHeading = styled.h1\` + \${TypographyHeadlineMobile.Headline}; +\`; +`; + +const TypographyCodeBlock = ({ children }: { children: JSX.Element }) => ( +
{children}
+); + +const InfoTemplate: Story = () => ( + +

Import the base typography styles into a project as global css:

+ + + +

+ Additionally, if a Heading needs specific styles, like the{' '} + Headline, use the following approach: +

+ + + +
+); + +export const TypographyExample = InfoTemplate.bind({}); +TypographyExample.storyName = 'Typography'; diff --git a/packages/utils/package.json b/packages/utils/package.json index 14a687168..ebd7dd8ee 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -24,6 +24,11 @@ "@emotion/styled": ">=11.3 <12", "lodash": ">=4.17.21 <5" }, + "devDependencies": { + "@atlaskit/code": "14.1.3", + "@storybook/react": "6.4.10", + "styled-components": "5.3.1" + }, "publishConfig": { "access": "public" }, diff --git a/packages/utils/src/Utils.stories.tsx b/packages/utils/src/Utils.stories.tsx new file mode 100644 index 000000000..780a1022f --- /dev/null +++ b/packages/utils/src/Utils.stories.tsx @@ -0,0 +1,298 @@ +import { CodeBlock } from '@atlaskit/code'; +import styled from '@emotion/styled'; +import { Meta, Story } from '@storybook/react'; + +import { Typography } from '../../typography'; + +import { mediaQuery, MediaQuery } from './mediaQuery'; +import { padding } from './spacing'; +import { VariantTemplate } from './storyTemplate'; + +export default { + title: 'UI Helpers/Utils', + parameters: { + layout: 'fullscreen' + } +} as Meta; + +const Wrapper = styled.div` + ${Typography.Body1}; + margin: 20px auto 0; + display: flex; + flex-direction: column; + width: 94% !important; + p { + padding: 10px 0; + span { + line-height: 1; + margin: 0 2px; + padding: 2px 4px; + white-space: nowrap; + border-radius: 3px; + font-size: 13px; + border: 1px solid #eeeeee; + color: rgba(51, 51, 51, 0.9); + background-color: #f8f8f8; + } + } +`; + +const Heading = styled.h4` + ${Typography.Heading4}; + padding: 10px 0; +`; + +const utilsCode = ` +css\` + \${padding(variant({ variants: { default: getThemeValue('themeValue') } }))} +\`; +`; + +const UtilsCodeBlock = ({ children }: { children: JSX.Element }) => ( +
{children}
+); + +const UtilsTemplate = () => ( + +

+ The utils provided under the @tablecheck/tablekit-utils{' '} + package are as follows. +

+

+ NOTE: A props function means a function that accepts a + single Object as arguments, that object should have the theme{' '} + context object defined on it. The theme object is injected + into all interpolated functions in + styled.xyz components and any component wrapped with{' '} + withTheme from + emotion-theming. +

+ Chaining and auto props function resolution +

+ css, variant, getThemeValue,{' '} + padding and margin will recursively resolve + functions by assuming that the function expects props. This allows us to + easily chain the convenience functions as follows +

+ + + +
+); + +export const Information = UtilsTemplate.bind({}); + +const paddinfMarginCode = ` +padding({ top: 12, left: '12%', right: '12px' }); // applies correctly +padding('12px'); // sets all padding values to 12px +padding(12); // sets all padding values to 12px +padding(({ isCompact }) => ({ left: isCompact ? 3 : 6 })); +`; + +const ResponsiveComponent = styled.div` + background-color: grey; + margin: 20px; + ${mediaQuery( + { + 'min-width: 800px': 20, + 'min-width: 1200px': 80, + default: { top: 10, left: 40, bottom: 80, right: 20 } + }, + padding as any + )}; +`; + +// NOTE that you would preferably use `variant` instead of this format +// See the variant example +const ResponsiveProps = styled.div<{ space: MediaQuery }>` + background-color: grey; + margin: 20px; + ${mediaQuery('space', padding as any)}; +`; + +const Inner = styled.div` + background-color: lightblue; + color: black; + text-align: center; + font-weight: bold; + padding: 20px; +`; + +const PaddingMarginTemplate: Story = () => ( + +

+ These functions allows consistent definitions of padding and margin + respecting isRtl on the theme, it returns a props function.{' '} + padding + can be directly swapped for margin in all following examples. +

+ + + + + Responsive Padding from Props + + + Responsive Padding in Styles Definition + +
+); + +export const PaddingMargin = PaddingMarginTemplate.bind({}); +PaddingMargin.storyName = 'padding and margin'; + +const getThemeValueCode = ` +const getter = getThemeValue('component.color', 'blue'); +getter(); // will resolve to the fallback value and return 'blue' +getter({ theme: { component: { color: 'red' } } }); // will use the theme prop and return to 'red' +`; + +const GetThemeValueTemplate: Story = () => ( + +

+ A convenience function to retrieve a value off a theme - intended to be + used inside themedCss or styled blocks as it returns a props function. +

+ + + +
+); + +export const GetThemeValue = GetThemeValueTemplate.bind({}); +GetThemeValue.storyName = 'getThemeValue'; + +const hexToRgbaCode = ` +import { hexToRgba } from '@tablecheck/tablekit-utils'; + +hexToRgba('#7935D2', 0.3) === 'rgba(121,35,210,0.3)'; +`; + +const HexToRgbaTemplate: Story = () => ( + +

+ Used as an alternative to chroma(hexValue).alpha(0.3).css(){' '} + as the chroma library is rather large to include just for altering the + alpha of a color. +

+ + + +
+); + +export const HexToRgba = HexToRgbaTemplate.bind({}); +HexToRgba.storyName = 'hexToRgba'; + +const ifRtlCode = ` +styled.div\` + text-align: \${ifRtl('right', 'left')}; +\`; +`; + +const ifRtlTemplate: Story = () => ( + +

+ Inspired by excels iif function to help toggle between + options dependant on isRtl on the theme, returns a props + function +

+ + + +
+); + +export const ifRtl = ifRtlTemplate.bind({}); +ifRtl.storyName = 'ifRtl'; + +const ResizingComponent = styled.div<{ + size: MediaQuery; + background: MediaQuery; +}>` + height: 60px; + margin: 20px; + display: flex; + justify-content: center; + align-items: center; + text-align: center; + color: black; + font-weight: bold; + border: 1px solid black; + padding: 10px; + ${mediaQuery('size', (currentSize = '80px') => `width: ${currentSize};`)} + ${mediaQuery( + ({ background }: any) => background, + (background = 'red') => `background-color: ${background};` + )} +`; + +const mediaQueryCode = ` +type QueryDefinitionType = string | { [string]: T }; + +function mediaQuery( + queriesOrGetter: QueryDefinitionType | ((props: *) => QueryDefinitionType), + renderer: (queryValue?: T) => string = (v) => v +): props => string | EmotionCssObject +`; + +const mediaQueryTemplate: Story = () => ( + +

+ The mediaQuery function is provided as a shortcut to help + with changing prop values based on media queries. The intent of this + function was to support changing the "size" prop as used in{' '} + @tablecheck/tablekit-input and{' '} + @tablecheck/tablekit-button + in different browser sizes without having to add in additional elements. +

+ + + +
+

Component widths change at 800px

+ + With Default + + + Without Default + +
+
+); + +export const MediaQueryStory = mediaQueryTemplate.bind({}); +MediaQueryStory.storyName = 'mediaQuery'; + +export const variantExample = VariantTemplate.bind({}); +variantExample.storyName = 'variant'; diff --git a/packages/utils/src/storyTemplate.tsx b/packages/utils/src/storyTemplate.tsx new file mode 100644 index 000000000..4824f2b1b --- /dev/null +++ b/packages/utils/src/storyTemplate.tsx @@ -0,0 +1,132 @@ +import { CodeBlock } from '@atlaskit/code'; +import { css } from '@emotion/react'; +import styled from '@emotion/styled'; +import { Story } from '@storybook/react'; + +import { Link, Typography } from '../../typography'; + +import { variant } from './variant'; + +const Wrapper = styled.div` + ${Typography.Body1}; + margin: 20px auto 0; + display: flex; + flex-direction: column; + width: 94% !important; + p { + padding: 10px 0; + span { + line-height: 1; + margin: 0 2px; + padding: 2px 4px; + white-space: nowrap; + border-radius: 3px; + font-size: 13px; + border: 1px solid #eeeeee; + color: rgba(51, 51, 51, 0.9); + background-color: #f8f8f8; + } + } +`; + +const Heading = styled.h4` + ${Typography.Heading4}; + padding: 10px 0; +`; + +export const UtilsCodeBlock = ({ + children +}: { + children: JSX.Element; +}): JSX.Element =>
{children}
; + +const StyledVariant = styled.div<{ interactionState: string }>` + ${variant({ + prop: 'interactionState', + variants: { + default: css` + color: blue; + `, + active: css` + color: green; + `, + danger: css` + color: red; + ` + } + })} +`; + +const VariantCode1 = ` +const StyledVariant = styled.div\` + \${variant({ + prop: 'interactionState', + variants: { + default: css\` + color: blue; + \`, + active: css\` + color: green; + \`, + danger: css\` + color: red; + \` + } + })} +\`; + +; +`; + +const VariantCode2 = ` +.StyledVariant:not(.active):not(.disabled) { + color: blue; +} + +.StyledVariant.active { + color: green; +} + +.StyledVariant.danger { + color: red; +} +`; + +export const VariantTemplate: Story = () => ( + +

+ A fork of{' '} + + @xstyled variant + {' '} + utility. +

+

+ This variant uses the value passed in the props of the styled component to + select the correct value. This is most commonly used with the{' '} + appearance prop. The passed prop may also be a{' '} + MediaQueryObject object where different media queries return + different results. There is also the additional property called{' '} + useVariantAsClass which renders the variants as classes, + useful for third party integration. +

+ useVariantAsClass +

+ An example of this is used in the @tablecheck/tablekit-item{' '} + component for us to support react-router's NavLink{' '} + component that requires usage of either a activeClassName or{' '} + activeStyles prop. The values for + useVariantAsClass are either keyof Props or a{' '} + keyof Props[] +

+ Text is green +
+ + + +

The above code will generate the following stylesheet:

+ + + +
+);