diff --git a/next/components/example-box/index.tsx b/next/components/example-box/index.tsx deleted file mode 100644 index c63e35bb..00000000 --- a/next/components/example-box/index.tsx +++ /dev/null @@ -1,7 +0,0 @@ -import React from 'react'; - -function ExampleBox({ children }: { children: React.ReactNode }): JSX.Element { - return
{children}
; -} - -export default ExampleBox; diff --git a/next/components/mdx/components.tsx b/next/components/mdx/components.tsx index 1ea2ba24..ff046af1 100644 --- a/next/components/mdx/components.tsx +++ b/next/components/mdx/components.tsx @@ -20,13 +20,6 @@ const sourceCodePro = Source_Code_Pro({ subsets: ['latin'], }); -// TODO: apply atomicClasses to other headers once -// type definition error is resolved (see H2) -interface HeadingElement - extends React.DetailedHTMLProps, HTMLHeadingElement> { - atomicClasses?: string; -} - const HashAnchor = ({ children, id }: { children: React.ReactNode; id: string }): JSX.Element => (

+ WCAG 2.1 AA success criterion + {' '} + for contrast for the current requirements. +

+

Color combinations

+

+ The color system is set up to provide an accessible experience by combining a + particular range of color values from Thumbprint. The combinations include any{' '} + 100-level color paired with any 600-level color + values. For example, when using the blue-100 background color, the{' '} + blue-600 color should be used for the text. +

+

100-level background

+

+ A common and preferred pattern for non-interactive elements when applying a + background color uses the 100-level values for backgrounds. The{' '} + 600-level color of the same hue will ensure an accessible color + contrast ratio combined with this background treatment.{' '} + Any value below the 600-level (500, 400, 300, 200, 100){' '} + will not meet the minimum CCR requirement, and the use of these + combinations should be avoided. +

+ + + +
+ + blue-600 + +
+
+ +
+ + indigo-600 + +
+
+ +
+ + purple-600 + +
+
+ +
+ + green-600 + +
+
+ +
+ + yellow-600 + +
+
+ +
+ + red-600 + +
+
+
+ +

White background

+

+ The foreground text should use the 500 value when using a{' '} + white background with the exclusion of yellow, which will require + the use of yellow-600. This combination ensures that the color + contrast ratio meets the 4.5:1 minimum.{' '} + Any value below the 500-level (400, 300, 200, 100){' '} + will not meet the minimum CCR requirement, and the use of these + combinations should be avoided. +

+ + + +
+ + blue-500 + +
+
+ +
+ + indigo-500 + +
+
+ +
+ + purple-500 + +
+
+ +
+ + green-500 + +
+
+ +
+ + yellow-600 + +
+
+ +
+ + red-500 + +
+
+
+ +

Neutral colors

+

+ When using a combination of neutral colors, not all combinations of colors will + provide an accessible experience. The following graph represents the minimum color + combinations expressed by the WCAG AA color contrast ratio and our established color + palette. +

+ + + +
+ + black-300 + +
+
+ +
+ + black-300 + +
+
+ +
+ + black + +
+
+ +
+ + gray-200 + +
+
+ +
+ + gray-300 + +
+
+
+ +

Avoid using color exclusively

+

+ Colors can also be used to convey information. For example, using red for error + messages or green for success messages can help users understand your interface more + quickly. Ultimately, accessible colors can help create a better experience for all + users, regardless of their abilities. +

+

+ However, color alone should not be used exclusively as an indicator for a user + experience especially when an action or response from the user is required. To + provide a more inclusive experience, additional information, such as supportive + text, should be included. +

+

+ For example, when expressing an error state on an input in a form, the input color + should provide a visual indicator that the element needs attention. However, the + color change should not be the sole indicator. The color change should be paired + with supportive text that gives the user more information on how to recover from the + error state. +

+

Implementations

+ +

Resources

+ + + ); +} diff --git a/next/pages/guidelines/color/accessibility.tsx b/next/pages/guidelines/color/accessibility.tsx deleted file mode 100644 index 0cb5740a..00000000 --- a/next/pages/guidelines/color/accessibility.tsx +++ /dev/null @@ -1,339 +0,0 @@ -import React from 'react'; -import type { InferGetStaticPropsType } from 'next'; -import { Grid, GridColumn, Text } from '@thumbtack/thumbprint-react'; -import * as tokens from '@thumbtack/thumbprint-tokens'; -import { ContentPage } from '../../../components/mdx/mdx'; -import getContentPageStaticProps from '../../../utils/get-content-page-static-props'; -import { CodeExperimental, H2, H3, LI, P, UL } from '../../../components/mdx/components'; - -export const getStaticProps = getContentPageStaticProps; - -export default function Accessibility({ - layoutProps, -}: InferGetStaticPropsType) { - return ( - -

- Color usage plays a key role in how we convey emotions, establishing brand identity, - and guiding user interactions. Consistent and thoughtful color choices also improve - usability, highlight important elements, and create a cohesive design language - across the product. -

- -

Accessibility

-

- Accessible colors are vital for those with color blindness or other vision - impairments. By using a high color contrast ratio, you can make sure that your - design is accessible to as many people as possible. -

-

Text styling

-

- All text, including text in images and link text, should have enough contrast to - stand out. This is especially important for links that aren’t underlined (and should - apply to all states, including default, hover, and focus). See{' '} - - WCAG 2.1 AA success criterion - {' '} - for contrast for the current requirements. -

-

Color combinations

-

- The color system is set up to provide an accessible experience by combining a - particular range of color values from Thumbprint. The combinations include any{' '} - 100-level color paired with any 600-level color - values. For example, when using the blue-100 background color, the{' '} - blue-600 color should be used for the text. -

- -

Low emphasis backgrounds

-

- A common and preferred pattern for non-interactive elements when applying a - background color uses the 100-level values for backgrounds. The{' '} - 600-level color of the same hue will ensure an accessible color - contrast ratio combined with this background treatment.{' '} - Any value below the 600-level (500, 400, 300, 200, 100){' '} - will not meet the minimum CCR requirement, and the use of these - combinations should be avoided. -

- -
- - -
- - blue-600 - -
-
- -
- - indigo-600 - -
-
- -
- - purple-600 - -
-
- -
- - green-600 - -
-
- -
- - yellow-600 - -
-
- -
- - red-600 - -
-
-
-
- -

High emphasis backgrounds

-

- When moments in the user experience call for bringing more emphasis to the moment, - then a darker value of of the color system can be used a background. These are more - commonly going to be used as a 500 (Yellow 600) value. White text or 100-level color - should be used. -

- -
- - -
- - white - -
-
- -
- - white - -
-
- -
- - white - -
-
- -
- - white - -
-
- -
- - white - -
-
- -
- - white - -
-
-
-
- -

White background

-

- The foreground text should use the 500 value when using a{' '} - white background with the exclusion of yellow, which will require - the use of yellow-600. This combination ensures that the color - contrast ratio meets the 4.5:1 minimum.{' '} - Any value below the 500-level (400, 300, 200, 100){' '} - will not meet the minimum CCR requirement, and the use of these - combinations should be avoided. -

- -
- - -
- - blue-500 - -
-
- -
- - indigo-500 - -
-
- -
- - purple-500 - -
-
- -
- - green-500 - -
-
- -
- - yellow-600 - -
-
- -
- - red-500 - -
-
-
-
- -

Neutral colors

-

- When using a combination of neutral colors, not all combinations of colors will - provide an accessible experience. The following graph represents the minimum color - combinations expressed by the WCAG AA color contrast ratio and our established color - palette. -

- -
- - -
- - black-300 - -
-
- -
- - black-300 - -
-
- -
- - black - -
-
- -
- - gray-200 - -
-
- -
- - gray-300 - -
-
-
-
- -

Avoid using color exclusively

-

- Colors can also be used to convey information. For example, using red for error - messages or green for success messages can help users understand your interface more - quickly. Ultimately, accessible colors can help create a better experience for all - users, regardless of their abilities. -

-

- However, color alone should not be used exclusively as an indicator for a user - experience especially when an action or response from the user is required. To - provide a more inclusive experience, additional information, such as supportive - text, should be included. -

-

- For example, when expressing an error state on an input in a form, the input color - should provide a visual indicator that the element needs attention. However, the - color change should not be the sole indicator. The color change should be paired - with supportive text that gives the user more information on how to recover from the - error state. -

-

Implementations

-
    -
  • - All color variables shown here available for SCSS and JS usage in{' '} - Thumbprint Tokens. -
  • -
  • - The "core" colors, as indicated by{' '} - (c), are available as classes in{' '} - Thumbprint Atomic for both{' '} - color and{' '} - background properties. -
  • -
-

Resources

- -
- ); -} diff --git a/next/pages/guidelines/color/overview.tsx b/next/pages/guidelines/color/overview.tsx deleted file mode 100644 index f6383158..00000000 --- a/next/pages/guidelines/color/overview.tsx +++ /dev/null @@ -1,200 +0,0 @@ -import React from 'react'; -import type { InferGetStaticPropsType } from 'next'; -import Link from 'next/link'; -import { ContentPage } from '../../../components/mdx/mdx'; -import getContentPageStaticProps from '../../../utils/get-content-page-static-props'; -import { H2, H3, P } from '../../../components/mdx/components'; -import usageContentMappings, { - usageContent, - emphasisContent, - interactionContent, - ContentMapping, -} from '../../../utils/guidelines/color/color-usage-mappings'; -import { Image } from '../../../utils/guidelines/color/color-usage-types'; -import ExampleBox from '../../../components/example-box'; - -import usage from '../../../images/pages/guide/product/color/overiew/usage.png'; -import emphasis from '../../../images/pages/guide/product/color/overiew/emphasis.png'; -import interaction from '../../../images/pages/guide/product/color/overiew/interaction.png'; - -const images: Image = { - usage: { - src: usage, - alt: 'alt text', - }, - emphasis: { - src: emphasis, - alt: 'alt text', - }, - interaction: { - src: interaction, - alt: 'alt text', - }, -}; - -export const getStaticProps = getContentPageStaticProps; - -function colorThemeTable({ type }: { type: string }): JSX.Element { - return ( - - - - - - - - - {Object.keys(usageContentMappings) - .filter(key => usageContentMappings[key].type === type) - .map(key => { - return ( - - - - - ); - })} - -
ValueDescription
- - - {key} - - - {usageContentMappings[key].description} -
- ); -} - -function OverviewTable({ list }: { list: ContentMapping }): JSX.Element { - return ( - - - - - - - - - {Object.keys(list).map(key => { - return ( - - - - - ); - })} - -
ValueDescription
- - {list[key].title} - - - {list[key].description} -
- ); -} - -export default function Overview({ layoutProps }: InferGetStaticPropsType) { - return ( - -

- Colors play a crucial role in communicating status, guidance, and providing visual - cues. Color should be used sparingly to drive focus to moments that matter. Color - should not be used to add personality or flair. -

- -
-

Color themes

-

- Our use of color can be defined in two major types classified as brand and - feedback colors. -

-
- -
-

Brand colors

-

- These colors are used to create a consistent visual identity and evoke specific - emotions or associations within a design system. -

- {colorThemeTable({ type: 'brand' })} -
- -
-

Feedback colors

-

- These colors are used to help re-enforce important moments in the user journey - that suggest or require additional guidance, gather user input, and improve the - user experience. -

- {colorThemeTable({ type: 'feedback' })} -
- - See all colors - -
-

Usage

-

- Color usage is arranged into four high-level categories background, border, text - and icon. Color usage patterns are represented by their intended use case. -

- -
- {images.usage.alt} -
-
- {OverviewTable({ list: usageContent })} -
- - Read more about color usage - -
-

Emphasis

-

- Not all experiences are treated equal. To provide varying levels of importance - in conjunction with the hue, we use levels of emphasis to draw the users - attention. A strong emphasis is high contrast in comparison to the surface the - component occupies. -

- -
- {images.emphasis.alt} -
-
- {OverviewTable({ list: emphasisContent })} -
- -
-

Interaction

-

- Status such as hover, selected, disabled, and others describe how users engage - with content. Not all elements are interactive, but our{' '} - color usage patterns {' '} - provide additional color definitions when applicable. -

- -
- {images.interaction.alt} -
-
- {OverviewTable({ list: interactionContent })} -
-
- ); -} diff --git a/next/pages/guidelines/color/palette.tsx b/next/pages/guidelines/color/palette.tsx deleted file mode 100644 index 9fb092f2..00000000 --- a/next/pages/guidelines/color/palette.tsx +++ /dev/null @@ -1,391 +0,0 @@ -import React, { useState } from 'react'; -import type { InferGetStaticPropsType } from 'next'; -import ClickableBox from 'clickable-box'; -import { groupBy } from 'lodash-es'; -import classNames from 'classnames'; -import * as tokens from '@thumbtack/thumbprint-tokens'; -import { NavigationCaretDownSmall, NavigationCaretUpSmall } from '@thumbtack/thumbprint-icons'; -import { Text } from '@thumbtack/thumbprint-react'; -import { ContentPage } from '../../../components/mdx/mdx'; -import getLayoutProps from '../../../utils/get-layout-props'; -import { H2, P } from '../../../components/mdx/components'; -import { paletteColortMappings } from '../../../utils/guidelines/color/color-usage-mappings'; -import { Color, Image, Usage } from '../../../utils/guidelines/color/color-usage-types'; - -import purple from '../../../images/pages/guide/product/color/palette/purple.png'; -import yellow from '../../../images/pages/guide/product/color/palette/yellow.png'; -import neutral from '../../../images/pages/guide/product/color/palette/neutral.png'; -import red from '../../../images/pages/guide/product/color/palette/red.png'; -import blue from '../../../images/pages/guide/product/color/palette/blue.png'; -import green from '../../../images/pages/guide/product/color/palette/green.png'; -import indigo from '../../../images/pages/guide/product/color/palette/indigo.png'; - -const images: Image = { - purple: { - src: purple, - alt: 'user interface example where purple colors are applied', - }, - yellow: { - src: yellow, - alt: 'user interface example where yellow colors are applied', - }, - neutral: { - src: neutral, - alt: 'user interface example where neutral colors are applied', - }, - red: { - src: red, - alt: 'user interface example where red colors are applied', - }, - blue: { - src: blue, - alt: 'user interface example where blue colors are applied', - }, - green: { - src: green, - alt: 'user interface example where green colors are applied', - }, - indigo: { - src: indigo, - alt: 'user interface example where indigo colors are applied', - }, -}; - -interface ColoredPillProps { - fill: string; - title: string; - value: string; -} - -function TokenPill({ fill, title, value }: ColoredPillProps): JSX.Element { - return ( -
-
{title}
-
- {value} -
-
- ); -} - -function ColorSection({ values }: { values: Color['values'] }): JSX.Element { - const [isActive, setIsActive] = useState(false); - return ( -
- {/* clickable region */} - setIsActive(!isActive)} - > -
- {values.color.replace('400', '')} - {values.level === '400' ? ( - - ) : null} -
- {!isActive ? : } -
- {/* end clickable region */} -
- {/* body content */} -
-
    - {values.description.split('\n').map(item => { - return
  • {item}
  • ; - })} -
-
- {/* tokens */} -
- - - - -
-
-
- ); -} - -interface SwatchProps { - tokenColor: string; - isCore?: boolean; - className?: string; -} - -function CoreColorPill({ tokenColor }: { tokenColor: string }): JSX.Element { - const bgColor = tokens[`tpColor${tokenColor?.replace('tpColor', '')}500`]; - return ( - - core - - ); -} - -function Swatch({ tokenColor, isCore, className }: SwatchProps): JSX.Element { - return ( - - {isCore ? : null} - - ); -} - -function renderColors({ usages }: { usages: Usage[] }): JSX.Element { - return ( -
- {Object.keys(usages) - .map(key => { - return ( -
-

{paletteColortMappings[key].title}

-

{paletteColortMappings[key].description}

- -
-
-
Suggested use
- - {paletteColortMappings[key].suggestedUse} - - -
- {usages[key].map((component: Usage) => { - return ( - - ); - })} -
-
- -
-
Examples
- {images[key].alt} -
-
-
- ); - }) - .sort((a, b) => { - const colorOrder = { - neutral: 1, - blue: 2, - indigo: 3, - purple: 4, - green: 5, - red: 6, - yellow: 7, - }; - if (!colorOrder[a.key] || !colorOrder[b.key]) { - throw new Error(`All colors must be defined in the \`colorOrder\` object.`); - } - return colorOrder[a.key] - colorOrder[b.key]; - })} -
- ); -} - -export default function Palette({ - usages, - layoutProps, -}: InferGetStaticPropsType) { - return ( - -

- Core colors are expanded into a range of values to support varying moments within - the product. The usage patterns for each value below can be found in our usage page. -

- -
-

Color system

-

- These colors should be used to drive the user experience depending on their - intended use case and should be used sparingly to drive focus to moments that - matter from a branded or feedback perspective. -

-
- - {/* palette */} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Neutral - - 100 - - 200 - - 300 - - Core - - 500 - - 600 -
- Netural -
- Blue -
- Green -
- Yellow -
- Red -
- Indigo -
- Purple -
- - {/* colors */} - {renderColors({ usages })} -
- ); -} - -export const getStaticProps = async () => { - const listRowsRes = await fetch( - // https://coda.io/developers/apis/v1#operation/listRows - `https://coda.io/apis/v1/docs/bXyUQb2tJW/tables/grid-oefPpAQq-z/rows?useColumnNames=true`, - { - headers: { - Authorization: `Bearer ${process.env.CODA_API_TOKEN}`, - }, - }, - ); - - const data = listRowsRes.ok ? await listRowsRes.json() : null; - const usages: Usage[] = data ? data.items : []; - - const groupedUsages = groupBy(usages, usage => { - return usage.values.family; - }); - - return { - props: { - layoutProps: getLayoutProps(), - usages: groupedUsages, - }, - }; -}; diff --git a/next/pages/guidelines/color/usage/background.tsx b/next/pages/guidelines/color/usage/background.tsx deleted file mode 100644 index 234bc8f4..00000000 --- a/next/pages/guidelines/color/usage/background.tsx +++ /dev/null @@ -1,157 +0,0 @@ -import React from 'react'; -import type { InferGetStaticPropsType } from 'next'; -import { groupBy } from 'lodash-es'; -import { ContentPage } from '../../../../components/mdx/mdx'; -import Alert from '../../../../components/alert/alert'; -import InlineCode from '../../../../components/inline-code/inline-code'; -import getLayoutProps from '../../../../utils/get-layout-props'; -import { H2, H3, LI, P, UL } from '../../../../components/mdx/components'; -import ExampleBox from '../../../../components/example-box'; -import UsageCategory from '../../../../utils/guidelines/color/color-usage-categories'; -import ColorUsageNav from '../../../../utils/guidelines/color/color-usage-nav'; -import { Usage, Image } from '../../../../utils/guidelines/color/color-usage-types'; - -import intro from '../../../../images/pages/guide/product/color/usage/background/intro.png'; -import neutral from '../../../../images/pages/guide/product/color/usage/background/neutral.png'; -import primary from '../../../../images/pages/guide/product/color/usage/background/primary.png'; -import success from '../../../../images/pages/guide/product/color/usage/background/success.png'; -import guidance from '../../../../images/pages/guide/product/color/usage/background/guidance.png'; -import alert from '../../../../images/pages/guide/product/color/usage/background/alert.png'; -import caution from '../../../../images/pages/guide/product/color/usage/background/caution.png'; -import accent from '../../../../images/pages/guide/product/color/usage/background/accent.png'; - -const images: Image = { - neutral: { - src: neutral, - alt: 'user interface example where the netural theme is applied to element backgrounds', - }, - primary: { - src: primary, - alt: 'user interface example where the primary theme is applied to element backgrounds', - }, - success: { - src: success, - alt: 'user interface example where the success theme is applied to element backgrounds', - }, - guidance: { - src: guidance, - alt: 'user interface example where the guidance theme is applied to element backgrounds', - }, - alert: { - src: alert, - alt: 'user interface example where the alert theme is applied to element backgrounds', - }, - caution: { - src: caution, - alt: 'user interface example where the caution theme is applied to element backgrounds', - }, - accent: { - src: accent, - alt: 'user interface example where the accent theme is applied to element backgrounds', - }, -}; - -export default function UsageBackground({ - usages, - layoutProps, -}: InferGetStaticPropsType) { - return ( - - {usages.length === 0 && ( - - You’ll need to add CODA_API_TOKEN environment variable - to a www/.env file in order to see the component - statuses while developing locally. Read the{' '} - - CONTRIBUTING.md - {' '} - file for help. - - )} - -

- The use of color plays a key role in how we convey emotions, establish brand - identity, and guide user interactions. Consistent and thoughtful color choices also - improve usability, highlight important elements, and create a cohesive design - language across the product. -

- - - - -
- -
-
- -
-

Background colors

-

- Backgrounds foundational determine color usage hierarchically. Text, borders, - and icon color usage will vary depending on the background surface color. -

- -

- To build a sense of elevation, backgrounds can also be layered on top of one - another. For example, a pill within a card can use color to build a visual - indexing importance that can be dictated by color. -

- -

- Levels of emphasis can also be used to further accentuate the importance of - specific areas of the UI. By default, toasts use a high emphasis background to - drive impact to meaningful and timely moments. -

-
-
-

General principles

-
    -
  • Use neutral values for pages/views
  • {' '} -
  • - Core Primary color (Blue 400) is reserved for interactive elements (ex: - Button) -
  • {' '} -
  • Colors designated for feedback should be used sparingly
  • -
  • Avoid mixing color surfaces
  • -
-
- - -
- ); -} - -export const getStaticProps = async () => { - const listRowsRes = await fetch( - // https://coda.io/developers/apis/v1#operation/listRows - `https://coda.io/apis/v1/docs/bXyUQb2tJW/tables/grid-jzs5ByTkFj/rows?useColumnNames=true`, - { - headers: { - Authorization: `Bearer ${process.env.CODA_API_TOKEN}`, - }, - }, - ); - - const data = listRowsRes.ok ? await listRowsRes.json() : null; - const usages: Usage[] = data ? data.items : []; - const filteredImplementations = usages.filter(item => item.values.usage === 'background'); - - const groupedUsages = groupBy(filteredImplementations, usage => { - return usage.values.theme; - }); - - return { - props: { - layoutProps: getLayoutProps(), - usages: groupedUsages, - }, - }; -}; diff --git a/next/pages/guidelines/color/usage/borders.tsx b/next/pages/guidelines/color/usage/borders.tsx deleted file mode 100644 index 49a49835..00000000 --- a/next/pages/guidelines/color/usage/borders.tsx +++ /dev/null @@ -1,102 +0,0 @@ -import React from 'react'; -import type { InferGetStaticPropsType } from 'next'; -import { groupBy } from 'lodash-es'; -import { ContentPage } from '../../../../components/mdx/mdx'; -import { H2, H3, LI, P, UL } from '../../../../components/mdx/components'; -import getLayoutProps from '../../../../utils/get-layout-props'; -import ExampleBox from '../../../../components/example-box'; -import UsageCategory from '../../../../utils/guidelines/color/color-usage-categories'; -import ColorUsageNav from '../../../../utils/guidelines/color/color-usage-nav'; -import { Usage, Image } from '../../../../utils/guidelines/color/color-usage-types'; - -import intro from '../../../../images/pages/guide/product/color/usage/borders/intro.png'; -import neutral from '../../../../images/pages/guide/product/color/usage/borders/neutral.png'; -import guidance from '../../../../images/pages/guide/product/color/usage/borders/guidance.png'; - -const images: Image = { - neutral: { - src: neutral, - alt: 'user interface example where neutral colors are applied to borders', - }, - guidance: { - src: guidance, - alt: 'user interface example where guidance colors are applied to borders', - }, -}; - -export default function UsageBorders({ - usages, - layoutProps, -}: InferGetStaticPropsType) { - return ( - -

- The use of color plays a key role in how we convey emotions, establish brand - identity, and guide user interactions. Consistent and thoughtful color choices also - improve usability, highlight important elements, and create a cohesive design - language across the product. -

- - - - -
- -
-
- -
-

Border colors

-

- Borders are used in product design to visually separate or delineate elements, - create hierarchy, and provide structure to the overall layout. -

-
- -
-

General principles

-
    -
  • Use neutral values on non-interactive moments
  • -
  • - Borders are not used with colored backgrounds to accentuate separation or - elevation (excludes map overlays) -
  • -
  • Default border is Gray 300
  • -
-
- - -
- ); -} - -export const getStaticProps = async () => { - const listRowsRes = await fetch( - // https://coda.io/developers/apis/v1#operation/listRows - `https://coda.io/apis/v1/docs/bXyUQb2tJW/tables/grid-jzs5ByTkFj/rows?useColumnNames=true`, - { - headers: { - Authorization: `Bearer ${process.env.CODA_API_TOKEN}`, - }, - }, - ); - - const data = listRowsRes.ok ? await listRowsRes.json() : null; - const usages: Usage[] = data ? data.items : []; - const filteredImplementations = usages.filter(item => item.values.usage === 'border'); - - const groupedUsages = groupBy(filteredImplementations, usage => { - return usage.values.theme; - }); - - return { - props: { - layoutProps: getLayoutProps(), - usages: groupedUsages, - }, - }; -}; diff --git a/next/pages/guidelines/color/usage/icons.tsx b/next/pages/guidelines/color/usage/icons.tsx deleted file mode 100644 index 01f7e95f..00000000 --- a/next/pages/guidelines/color/usage/icons.tsx +++ /dev/null @@ -1,130 +0,0 @@ -import React from 'react'; -import type { InferGetStaticPropsType } from 'next'; -import { groupBy } from 'lodash-es'; -import { ContentPage } from '../../../../components/mdx/mdx'; -import { H2, H3, LI, P, UL } from '../../../../components/mdx/components'; -import getLayoutProps from '../../../../utils/get-layout-props'; -import ExampleBox from '../../../../components/example-box'; -import UsageCategory from '../../../../utils/guidelines/color/color-usage-categories'; -import ColorUsageNav from '../../../../utils/guidelines/color/color-usage-nav'; -import { Usage, Image } from '../../../../utils/guidelines/color/color-usage-types'; - -import intro from '../../../../images/pages/guide/product/color/usage/icons/intro.png'; -import neutral from '../../../../images/pages/guide/product/color/usage/icons/neutral.png'; -import primary from '../../../../images/pages/guide/product/color/usage/icons/primary.png'; -import success from '../../../../images/pages/guide/product/color/usage/icons/success.png'; -import guidance from '../../../../images/pages/guide/product/color/usage/icons/guidance.png'; -import alert from '../../../../images/pages/guide/product/color/usage/icons/alert.png'; -import caution from '../../../../images/pages/guide/product/color/usage/icons/caution.png'; -import accent from '../../../../images/pages/guide/product/color/usage/icons/accent.png'; - -const images: Image = { - neutral: { - src: neutral, - alt: 'user interface example where neutral colors are applied to icons', - }, - primary: { - src: primary, - alt: 'user interface example where primary colors are applied to icons', - }, - success: { - src: success, - alt: 'user interface example where success colors are applied to icons', - }, - guidance: { - src: guidance, - alt: 'user interface example where guidance colors are applied to icons', - }, - alert: { - src: alert, - alt: 'user interface example where alert colors are applied to icons', - }, - caution: { - src: caution, - alt: 'user interface example where caution colors are applied to icons', - }, - accent: { - src: accent, - alt: 'user interface example where accent colors are applied to icons', - }, -}; - -export default function UsageIcons({ - usages, - layoutProps, -}: InferGetStaticPropsType) { - return ( - -

- The use of color plays a key role in how we convey emotions, establish brand - identity, and guide user interactions. Consistent and thoughtful color choices also - improve usability, highlight important elements, and create a cohesive design - language across the product. -

- - - - -
- -
-
- -
-

Icons

-

- Icons provide visual cues in the user experience and improve recognition by - conveying information in a compact and easily recognizable form. Use of color in - icons should coordinate with the space they occupy and any text. -

-
-
-

General principles

-
    -
  • Use neutral Black as default
  • -
  • - Color icons can be paired with text of same emphasis or neutral (strong) -
  • -
  • - Avoid pairing icon emphasis or colors with text or backgrounds of different - colors -
  • -
  • Icons should be singular solid color
  • -
-
- - -
- ); -} - -export const getStaticProps = async () => { - const listRowsRes = await fetch( - // https://coda.io/developers/apis/v1#operation/listRows - `https://coda.io/apis/v1/docs/bXyUQb2tJW/tables/grid-jzs5ByTkFj/rows?useColumnNames=true`, - { - headers: { - Authorization: `Bearer ${process.env.CODA_API_TOKEN}`, - }, - }, - ); - - const data = listRowsRes.ok ? await listRowsRes.json() : null; - const usages: Usage[] = data ? data.items : []; - const filteredImplementations = usages.filter(item => item.values.usage === 'icon'); - - const groupedUsages = groupBy(filteredImplementations, usage => { - return usage.values.theme; - }); - - return { - props: { - layoutProps: getLayoutProps(), - usages: groupedUsages, - }, - }; -}; diff --git a/next/pages/guidelines/color/usage/text.tsx b/next/pages/guidelines/color/usage/text.tsx deleted file mode 100644 index b7961513..00000000 --- a/next/pages/guidelines/color/usage/text.tsx +++ /dev/null @@ -1,134 +0,0 @@ -import React from 'react'; -import type { InferGetStaticPropsType } from 'next'; -import Link from 'next/link'; -import { groupBy } from 'lodash-es'; -import { ContentPage } from '../../../../components/mdx/mdx'; -import { H2, H3, LI, P, UL } from '../../../../components/mdx/components'; -import getLayoutProps from '../../../../utils/get-layout-props'; -import ExampleBox from '../../../../components/example-box'; -import UsageCategory from '../../../../utils/guidelines/color/color-usage-categories'; -import ColorUsageNav from '../../../../utils/guidelines/color/color-usage-nav'; -import { Usage, Image } from '../../../../utils/guidelines/color/color-usage-types'; - -import intro from '../../../../images/pages/guide/product/color/usage/text/intro.png'; -import neutral from '../../../../images/pages/guide/product/color/usage/text/neutral.png'; -import primary from '../../../../images/pages/guide/product/color/usage/text/primary.png'; -import success from '../../../../images/pages/guide/product/color/usage/text/success.png'; -import guidance from '../../../../images/pages/guide/product/color/usage/text/guidance.png'; -import alert from '../../../../images/pages/guide/product/color/usage/text/alert.png'; -import caution from '../../../../images/pages/guide/product/color/usage/text/caution.png'; -import accent from '../../../../images/pages/guide/product/color/usage/text/accent.png'; - -const images: Image = { - neutral: { - src: neutral, - alt: 'user interface example where neutral colors are applied to text', - }, - primary: { - src: primary, - alt: 'user interface example where primary colors are applied to text', - }, - success: { - src: success, - alt: 'user interface example where success colors are applied to text', - }, - guidance: { - src: guidance, - alt: 'user interface example where guidance colors are applied to text', - }, - alert: { - src: alert, - alt: 'user interface example where alert colors are applied to text', - }, - caution: { - src: caution, - alt: 'user interface example where caution colors are applied to text', - }, - accent: { - src: accent, - alt: 'user interface example where accent colors are applied to text', - }, -}; - -export default function UsageText({ - usages, - layoutProps, -}: InferGetStaticPropsType) { - return ( - -

- The use of color plays a key role in how we convey emotions, establish brand - identity, and guide user interactions. Consistent and thoughtful color choices also - improve usability, highlight important elements, and create a cohesive design - language across the product. -

- - - - -
- -
-
- -
-

Text

-

- Text color can vary depending on the background surface. By default, text color - should be neutral when on a neutral background (see{' '} - Accessibility for more - information WCAG color contrast ratio requirements. -

-
-
-

General principles

-
    -
  • Use neutral values for general heading (strong) and body copy (default)
  • -
  • Primary (Blue 400) is reserved for link color
  • -
  • Use sparingly
  • -
  • - Refer to color themes for - brand or feedback color guidelines -
  • -
  • - Bold text should be at least 18.5px and 24px for non-bold copy on core - values. -
  • -
-
- - -
- ); -} - -export const getStaticProps = async () => { - const listRowsRes = await fetch( - // https://coda.io/developers/apis/v1#operation/listRows - `https://coda.io/apis/v1/docs/bXyUQb2tJW/tables/grid-jzs5ByTkFj/rows?useColumnNames=true`, - { - headers: { - Authorization: `Bearer ${process.env.CODA_API_TOKEN}`, - }, - }, - ); - - const data = listRowsRes.ok ? await listRowsRes.json() : null; - const usages: Usage[] = data ? data.items : []; - const filteredImplementations = usages.filter(item => item.values.usage === 'text'); - - const groupedUsages = groupBy(filteredImplementations, usage => { - return usage.values.theme; - }); - - return { - props: { - layoutProps: getLayoutProps(), - usages: groupedUsages, - }, - }; -}; diff --git a/next/utils/get-layout-props.ts b/next/utils/get-layout-props.ts index 4ab4147a..8563d89e 100644 --- a/next/utils/get-layout-props.ts +++ b/next/utils/get-layout-props.ts @@ -63,19 +63,7 @@ export default function getLayoutProps(): LayoutProps { { title: 'Aspect ratio', href: '/guidelines/aspect-ratio' }, { title: 'Brand assets', href: '/guidelines/brand-assets' }, { title: 'Breakpoints', href: '/guidelines/breakpoints' }, - { - title: 'Color', - href: '/guidelines/color/overview', - sections: [ - { title: 'Overview', href: '/guidelines/color/overview' }, - { title: 'Palette', href: '/guidelines/color/palette' }, - { - title: 'Usage', - href: '/guidelines/color/usage/background', - }, - { title: 'Accessibility', href: '/guidelines/color/accessibility' }, - ], - }, + { title: 'Color', href: '/guidelines/color' }, { title: 'Design tokens', href: '/guidelines/design-tokens' }, { title: 'Iconography', href: '/guidelines/iconography' }, { title: 'Loaders', href: '/guidelines/loaders' }, diff --git a/next/utils/guidelines/color/color-usage-categories.tsx b/next/utils/guidelines/color/color-usage-categories.tsx deleted file mode 100644 index 37ed29db..00000000 --- a/next/utils/guidelines/color/color-usage-categories.tsx +++ /dev/null @@ -1,112 +0,0 @@ -import React from 'react'; -import usageContentMappings from './color-usage-mappings'; -import ExampleBox from '../../../components/example-box'; -import { H2, P } from '../../../components/mdx/components'; -import { Usage, Image } from './color-usage-types'; - -function showInteractionColumn(usages: [Usage]): number { - return usages.filter(item => item.values.interaction !== '').length; -} - -export default function UsageCategory({ - usages, - images, -}: { - usages: Usage[]; - images: Image[]; -}): JSX.Element { - return ( -
- {Object.keys(usages) - .map(key => { - return ( -
- {usageContentMappings[key] ? ( -
-

{usageContentMappings[key].title}

-

{usageContentMappings[key].description}

-
- ) : ( -
- Add missing {key} to usage content mapping -
- )} - - - - - - - {showInteractionColumn(usages[key]) > 0 ? ( - - ) : null} - - - - - {usages[key].map(component => { - return ( - - - - {showInteractionColumn(usages[key]) > 0 ? ( - - ) : null} - - - ); - })} - -
ColorEmphasisInteractionDescription
-
- - {component.values.color.replace('400', '')} -
-
- {component.values.emphasis} - - {component.values.interaction} - - {component.values.description} -
- {images[key] ? ( -
- Examples - -
- {images[key].alt} -
-
-
- ) : null} -
- ); - }) - .sort((a, b) => { - const themeOrder = { - neutral: 1, - primary: 2, - guidance: 3, - accent: 4, - success: 5, - alert: 6, - caution: 7, - input: 8, - }; - if (!themeOrder[a.key] || !themeOrder[b.key]) { - throw new Error(`All themes must be defined in the \`themeOrder\` object.`); - } - return themeOrder[a.key] - themeOrder[b.key]; - })} -
- ); -} diff --git a/next/utils/guidelines/color/color-usage-mappings.ts b/next/utils/guidelines/color/color-usage-mappings.ts deleted file mode 100644 index 8c688fac..00000000 --- a/next/utils/guidelines/color/color-usage-mappings.ts +++ /dev/null @@ -1,187 +0,0 @@ -export interface ContentMapping { - [key: string]: { - title: string; - type?: string; - color?: string; - suggestedUse?: string; - description: string; - }; -} -const usageContentMappings: ContentMapping = { - neutral: { - title: 'Neutral', - type: 'brand', - color: '#2f3033', - description: - 'Use to express default and less-opinionated UI elements such as background colors, icons, and text elements.', - }, - primary: { - title: 'Primary and info', - type: 'brand', - color: '#009fd9', - description: - 'Use our brand color to tie in the most important user moments with how we express ourselves as an organization through our identity. You can also use these in info moments.', - }, - guidance: { - title: 'Guidance and visualizations', - type: 'brand', - color: '#5968e2', - description: - 'Use to communicate guide posts such as onboarding moments and newly introduced product features.', - }, - accent: { - title: 'Accents', - type: 'brand', - color: '#8d56eb', - description: 'Use as a subtle background for accent purposes. ', - }, - success: { - title: 'Success, finance and ratings', - type: 'feedback', - color: '#2db783', - description: - 'Use for positive momentary moments, like income patterns, discounts, savings, and revenue growth.', - }, - alert: { - title: 'Alert', - type: 'feedback', - color: '#ff5a5f', - description: - 'Use to convey a sense of urgency, to assist in preventing potential errors or security issues, and for negative monetary moments like revenue loss.', - }, - caution: { - title: 'Caution', - type: 'feedback', - color: '#febe14', - description: - "Use for moments that are trending in a negative direction, but don't require the user to take immediate action.", - }, -}; - -export const usageContent: ContentMapping = { - background: { - title: 'Background', - description: 'Lowest level UI element where other UI element stack on top', - }, - border: { - title: 'Border', - description: 'Stroke around container element', - }, - text: { - title: 'Text', - description: 'Written language intended to clarity intention of element or interaction', - }, - icon: { - title: 'Icon', - description: 'Visual support for UI element', - }, -}; - -export const emphasisContent: ContentMapping = { - default: { - title: 'Default', - description: 'Approach with no variables introduced', - }, - low: { - title: 'Low', - description: 'Visually subdued moments', - }, - medium: { - title: 'Medium', - description: 'Increased level of importance in the UI', - }, - strong: { - title: 'Strong', - description: 'High level of importance or impact', - }, - inverse: { - title: 'Inverse', - description: 'Opposing end of default behavior', - }, -}; - -export const interactionContent: ContentMapping = { - default: { - title: 'Default', - description: 'No user engagement has taken place', - }, - hover: { - title: 'Low', - description: 'Cursor is placed above the element', - }, - selected: { - title: 'Medium', - description: 'Enabled state after user has pressed', - }, - visited: { - title: 'Strong', - description: 'State of link after user has viewed href in their browser', - }, - disabled: { - title: 'Inverse', - description: 'User can no longer engage with the element', - }, -}; - -export const paletteColortMappings: ContentMapping = { - neutral: { - title: 'Neutral', - type: 'brand', - color: '#2f3033', - suggestedUse: 'Backgrounds, text, iconography, shadows.', - description: - 'Use to express default and less-opinionated UI elements such as background colors, icons, and text elements.', - }, - blue: { - title: 'Blue', - type: 'brand', - color: '#009fd9', - suggestedUse: - 'Buttons, links, information, progress, promotional moments, brand moments, selected states.', - description: - 'Use to drive focus and immediate attention to primary product moments. Overuse of this color is discouraged, so we can focus on the moments that matter.', - }, - indigo: { - title: 'Indigo', - type: 'brand', - color: '#5968e2', - suggestedUse: 'Data visualizations, informational moments, user assistance.', - description: - 'Use to guide users through onboarding, user assistance, map overlays, and data visualizations.', - }, - purple: { - title: 'Purple', - type: 'brand', - color: '#8d56eb', - suggestedUse: 'Data visualizations, informational moments, user assistance.', - description: 'Use as a subtle background for accent purposes.', - }, - green: { - title: 'Green', - type: 'brand', - color: '#ffffff', - suggestedUse: 'Positive moments, savings, discounts, upward trends, growth, ratings.', - description: - 'Use for ratings or to express growth, upward trends, financial moments (cost figures, savings, discounts, etc..), and positive feedback.', - }, - red: { - title: 'Red', - type: 'feedback', - color: '#2db783', - suggestedUse: - 'Feedback moments, alerts, negative impact, cancellations, deletions and urgency.', - description: - 'Use sparingly to not deter from important moments that require the user’s immediate attention.', - }, - yellow: { - title: 'Yellow', - type: 'feedback', - color: '#ff5a5f', - suggestedUse: - 'Feedback with a subtle sense of caution. Commonly used in alerts and toasts.', - description: - 'Use to bring additional energy to the ux and provide cautionary moments of user feedback.', - }, -}; - -export default usageContentMappings; diff --git a/next/utils/guidelines/color/color-usage-nav.tsx b/next/utils/guidelines/color/color-usage-nav.tsx deleted file mode 100644 index e5ad2fd5..00000000 --- a/next/utils/guidelines/color/color-usage-nav.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import React from 'react'; -import TabNav, { TabNavItem } from '../../../components/tab-nav/tab-nav'; - -interface TabProps { - [key: string]: { - name: string; - path: string; - }; -} - -const usageTabs: TabProps = { - background: { name: 'Background', path: '/guidelines/color/usage/background' }, - text: { name: 'Text', path: '/guidelines/color/usage/text' }, - borders: { name: 'Borders', path: '/guidelines/color/usage/borders' }, - icons: { name: 'Icons', path: '/guidelines/color/usage/icons' }, -}; - -const ColorUsageNav = ({ activeTab }: { activeTab: string }): JSX.Element => { - return ( - - {Object.keys(usageTabs).map(node => ( - -
{usageTabs[node].name}
-
- ))} -
- ); -}; - -export default ColorUsageNav; diff --git a/next/utils/guidelines/color/color-usage-types.ts b/next/utils/guidelines/color/color-usage-types.ts deleted file mode 100644 index f9595749..00000000 --- a/next/utils/guidelines/color/color-usage-types.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { StaticImageData } from 'next/image'; - -interface Values { - usage: string; - theme: string; - 'light-hex': string; - color: string; - emphasis: string; - interaction: string; - description: string; - family: string; -} - -export interface Usage { - browserLink: string; - createdAt: string; - href: string; - id: string; - index: number; - name: string; - type: string; - updatedAt: string; - values: Values; -} - -interface ColorValues extends Values { - level: string; - 'pill-color': string; - javascript: string; - ios: string; - android: string; - scss: string; -} - -export interface Color { - browserLink: string; - createdAt: string; - href: string; - id: string; - index: number; - name: string; - type: string; - updatedAt: string; - key: string; - values: ColorValues; -} - -export interface Image { - [key: string]: { - src: StaticImageData; - alt: string; - }; -} - -export default Usage;