Braid Design System

repository·master·Indexed 23 days ago

https://github.com/seek-oss/braid-design-system

A themeable design system for the SEEK Group providing a collection of React components and styling primitives. It includes the @braid-design-system/docs-ui package for building documentation sites, @braid-design-system/source.macro for authoring type-checked code snippets, and @braid-design-system/codemod for automating version migrations. Braid utilizes Vanilla Extract for static CSS extraction and requires a BraidProvider for theme configuration.

Tokens
13.1K
Snippets
29
Records
74
Agent score
82%

What's inside Braid Design System

  1. Understand Braid's styling and runtime requirements

    master

    Braid relies on several technologies for styling and validation that may require specific bundler configurations:

    Styling with Vanilla Extract

    Braid uses Vanilla Extract for styling. This allows CSS to be authored in TypeScript and statically extracted at build time into atomic CSS classes. You will need a bundler plugin (like the one provided by Vanilla Extract) to collect these styles and inject them into your document or a separate stylesheet.

    Runtime Assertions

    Braid uses the assert library to perform precondition and invariant checking at runtime to ensure components are used correctly.

    • Recommendation: To avoid performance overhead in production, use unassert at build time (e.g., via babel-plugin-unassert) to strip these calls from your production bundle.

    Dev-time Warnings

    Braid provides warnings for deprecations and other communications based on process.env.NODE_ENV.

    • Recommendation: Ensure your bundler (e.g., Webpack) replaces process.env.NODE_ENV with a hardcoded string during the build process so that minifiers can perform dead-code elimination and remove these checks from production bundles.
  2. Handle space and touchableSize variables

    master

    The vars.space and vars.touchableSize variables are pre-multiplied by the grid. You no longer need to manually multiply them by theme.grid as you did in treat.

    -import { style } from 'sku/treat';
    +import { style } from '@vanilla-extract/css';
    +import { vars } from 'braid-design-system/css';
    
    -export const className = style(theme => ({
    -  padding: theme.space.standard * theme.grid,
    -  minHeight: theme.touchableSize * theme.grid
    -}));
    +export const className = style({
    +  padding: vars.space.standard,
    +  minHeight: vars.touchableSize
    +});
  3. Migrate to Braid v32+ (Compiled Source Code)

    master

    Starting with braid-design-system@32.0.0, the package is distributed as compiled JavaScript rather than TypeScript source code. This change improves build times for local and CI environments.

    Breaking Change: It is no longer possible to import APIs that are not exposed via explicit entrypoints. You must migrate away from any imports that reference internal file paths (e.g., braid-design-system/lib/...).

  4. Automate Braid Design System migrations with @braid-design-system/codemod

    master

    Use @braid-design-system/codemod to automate migrations between different versions of the Braid Design System. To run a migration, you must specify the target Braid version you are migrating to and a glob pattern that matches your project's source files.

    pnpm dlx @braid-design-system/codemod v31.11 "**/*.{ts,tsx}"
  5. Install vanilla-extract dependencies

    master

    To use vanilla-extract in your project with Braid, you must manually install the core package and optionally the CSS utilities for calculations.

    Install core CSS support:

    yarn add @vanilla-extract/css

    Install CSS utilities (required for performing themed style calculations):

    yarn add @vanilla-extract/css-utils
    yarn add @vanilla-extract/css
    # and optionally
    yarn add @vanilla-extract/css-utils
  6. Derive Component Prop Types

    master

    When creating custom components that wrap or forward props to Braid components, do not import types from internal paths. Instead, use React's ComponentProps utility to derive them from the component itself.

    Standard Components

    import { Text } from 'braid-design-system';
    import type { ComponentProps } from 'react';
    
    type TextProps = ComponentProps<typeof Text>;
    
    interface MyComponentProps {
      tone: TextProps['tone'];
    }

    Generic Components (e.g., Autosuggest)

    Because components like Autosuggest are generic, using ComponentProps<typeof Autosuggest> will result in unknown types. To maintain type safety, use TypeScript 4.7+ instantiation expressions to specialize the component first.

    Note: Requires TypeScript 4.7+ and sku@11.6.0 or higher.

    import type { ComponentProps } from 'react';
    import { Autosuggest } from 'braid-design-system';
    
    // A specialized Autosuggest component that only accepts `string`s
    const StringAutosuggest = Autosuggest<string>;
    type AutosuggestProps = ComponentProps<typeof StringAutosuggest>;
    
    type Value = AutosuggestProps['value'];
    
    const autosuggestValue: Value = {
      text: 'myValue',
      value: 'foo', // Correctly typed as string
    };

    Icon Slot Prop Types

    To derive the type for an icon slot, use an existing Braid icon component as a reference.

    import type { IconAdd } from 'braid-design-system';
    import type { ComponentProps, ReactElement } from 'react';
    
    type IconProps = ComponentProps<typeof IconAdd>;
    
    interface MyComponentProps {
      icon?: ReactElement<IconProps>;
    }
  7. Fix Internal Import Paths

    master

    If your project uses automatic IDE imports, you may have accidentally imported from private internal paths. These must be updated to use public entrypoints.

    Public Components

    Import components from the main entrypoint instead of their file paths.

    -import { Text } from 'braid-design-system/lib/components/Text/Text';
    +import { Text } from 'braid-design-system';

    Themes

    Import themes via the braid-design-system/themes entrypoint.

    -import { apac } from 'braid-design-system/lib/themes';
    -import apac from 'braid-design-system/lib/themes/apac';
    +import apac from 'braid-design-system/themes/apac';

    Styling APIs

    Import vars, atoms, and responsiveStyle via the braid-design-system/css entrypoint.

    -import { vars } from 'braid-design-system/lib/themes/vars.css';
    -import { atoms } from 'braid-design-system/lib/css/atoms/atoms';
    -import { responsiveStyle } from 'braid-design-system/lib/css/responsiveStyle';
    +import { vars, atoms, responsiveStyle } from 'braid-design-system/css';
    import { vars, atoms, responsiveStyle } from 'braid-design-system/css';
  8. Consume vanilla-extract styles in React

    master

    Unlike treat, you no longer need useStyles or styleRefs plumbing. You can access CSS exports directly from your .css.ts files, similar to how CSS Modules work.

    -import { useStyles } from 'react-treat';
    -import * as styleRefs from './styles.treat';
    +import * as styles from './styles.css';
    
    export const Foo = () => {
    -  const styles = useStyles(styleRefs);
    
      return (
        <div className={styles.root}>
          ...
        </div>
      );
    }
  9. Migrate away from `dividers` prop in layout components

    master
    Starting in Braid v33, layout components like Stack and Tiles have removed support for the dividers prop in favor of using CSS gap. This change reduces DOM depth and prevents unwanted spacing when children are hidden or null. To achieve the same visual result, you must now manually insert the Divider component into your layout where needed.
  10. Migrate `Stack` dividers to manual `Divider` components

    master

    To replace the dividers prop in a Stack, use the Divider component. The implementation depends on your rendering pattern:

    Static Children

    Manually interleave <Divider /> components between your components.

    Conditionally Rendered Children

    Wrap the conditional component and the <Divider /> in a React Fragment (<>...</>).

    Iterable Children

    Map through your items and return a React Fragment. Conditionally render the <Divider /> as the first child of the fragment for every item except the first (where index > 0).

    // For iterable children
    <Stack space="...">
      {items.map((item, index) => (
        <Fragment key={...}>
          {index > 0 ? <Divider /> : null}
          <Component>{item}</Component>
        </Fragment>
      ))}
    </Stack>
  11. Migrate from private useIcon API

    master

    If your application uses the private useIcon API for custom icons, you should migrate using one of the following strategies:

    1. Use a Braid Icon: Check if a suitable replacement exists in the Braid iconography suite.
    2. Contribute to Braid: If your icon is generic, consider contributing it to the Braid library via the #braid-support Slack channel.
    3. Use IconRenderer: For unique custom icons, migrate to the IconRenderer API to ensure consistent styling and accessibility. Refer to the Braid custom icon documentation for implementation details.