Cloudflare UI Framework

repository·master·Indexed 23 days ago

https://github.com/cloudflare/cf-ui

A collection of over 50 UI component packages used by Cloudflare to build interfaces. Built with React and a CSS-in-JS approach powered by Fela, it includes builder components for cards, pagination, and tables, as well as foundational components like Box, Button, Callout, and Card.

Tokens
50.2K
Snippets
136
Records
281
Agent score
79%

What's inside cf-ui

  1. Important notice: cf-ui is not maintained

    master
    The cf-ui repository is no longer maintained. Development has moved to an internal Cloudflare monorepo. While internal changes are periodically synchronized to this repository, pull requests are not accepted here. It is recommended to use this toolset only for building interfaces for Cloudflare-internal products.
  2. Prioritize functional testing for containers over unit testing user interactions

    master

    In the cf-ui architecture, logic is primarily managed via Redux (actions, reducers, and selectors). Because these are pure functions, they are easily unit tested. For UI components, the recommended strategy is:

    1. Keep State => UI Unit Tests: Continue writing unit tests that verify a component renders the correct UI given a specific state (e.g., checking if a list renders the correct number of items).
    2. Avoid User Interaction Unit Tests: Do not write unit tests that merely verify a component passes a prop to a child (e.g., checking if <UiComponent onClick={this.props.onClick}/> was written correctly). These tests are often redundant, difficult to work with when using shallow rendering, and provide little value beyond asserting that the code matches the test.
    3. Focus on Functional Testing for Containers: Instead of testing discrete units of interaction, write functional tests for containers. These tests should simulate a real user interaction and assert that the resulting side effects (like dispatched Redux actions or changes in the rendered UI tree) are correct.
  3. Use named media queries

    master

    The cf-style-provider includes a named-media-query plugin with a pre-configured set of media queries. Use these keys in your component style definitions to ensure consistent responsive behavior.

    Available Media Queries:

    • mobile: @media (min-width: 13.6em)
    • mobileWide: @media (min-width: 30.4em)
    • tablet: @media (min-width: 47.2em)
    • desktop: @media (min-width: 64em)
    • desktopLarge: @media (min-width: 97.6em)

    Example Usage:

    const Column = createComponent(() => ({
      color: 'black',
      desktop: {
        color: 'white'
      }
    }))
  4. How NotificationList and NotificationGlobalContainer work together

    master

    To manage and display notifications, use <NotificationList/> as a container for <Notification/> components. For global notifications, wrap the <NotificationList/> inside a <NotificationGlobalContainer/>.

    <NotificationGlobalContainer>
      <NotificationList>
        {notifications}
      </NotificationList>
    </NotificationGlobalContainer>
  5. Approach problem solving using a layered architecture

    master

    When building complex features or systems (such as React/Redux applications), avoid attempting to solve the entire problem from start to finish in a single pass. Instead, break the problem down into incremental layers. Each layer should be carefully considered, reviewed, and documented before moving to the next.

    Benefits of layering:

    • Allows for incremental progress and easier reviews.
    • Prevents 'tunnel vision' where you work toward an end-to-end solution without validating the foundations.
    • Enables the creation of reusable, open-sourceable libraries from the lower layers.
    • Improves the quality of the final API design.
  6. What are Selectors Lite™ and when to use them

    master

    Selectors Lite™ are getter functions used to abstract state lookups and filters out of components. While Redux actions and reducers handle most business logic, selectors are used for the remaining 10% of logic—specifically retrieving specific pieces of state or filtering collections—to keep components 'dumb' and focused on rendering.

    Use a selector when you find yourself performing logic like this directly in JSX:

    • Deeply nested state lookups: state.zones.all[state.zones.current].name
    • Filtering or mapping collections: state.zones.all.filter(zone => zone.isPartnerHosted)

    By replacing these with selector functions, you make components easier to test and refactor.

  7. Favor function composition over class inheritance

    master

    When contributing new code to cf-ui, avoid using class inheritance. Instead, favor composing plain functions together. Inheritance in JavaScript can lead to bugs caused by implicit dependencies on this, accidental modification of parent class properties, or breaking parent class methods by unintentionally changing the interface (e.g., failing to return a value in a subclass method that the parent class expects). Plain functions provide explicit dependencies via parameters and clearly defined outputs, making code paths easier to follow and logic easier to isolate.

    // Instead of inheritance:
    class Foo {
      method() {
        doSomething();
      }
    }
    
    class Bar extends Foo {
      method() {
        doSomethingElse();
        super.method();
      }
    }
    
    // Use function composition:
    function fooMethod() {
      doSomething();
    }
    
    function barMethod() {
      doSomethingElse();
      fooMethod();
    }
  8. How to use theme constants in cf-ui components

    master

    The cf-style-const package provides constants used to theme cf-ui, cf-ux, and other Fela-based components.

    Important: You should not import these constants directly. Instead, the variables are automatically passed through the React component tree via this.context.theme in projects using CSS-in-JS.

    To access these theme variables in your own components, use a Higher-Order Component (HOC) like createComponent() from cf-style-container. This HOC wires this.context.theme into props.theme, making the constants available as props.

  9. Set up cf-ui with Fela CSS-in-JS

    master

    cf-ui components use CSS-in-JS powered by Fela. To use these components, you must include a StyleProvider (from cf-style-provider) in the context of your React application. The StyleProvider is responsible for rendering the component styles into <style> nodes.

    import React from 'react';
    import ReactDOM from 'react-dom';
    import { StyleProvider } from 'cf-style-provider';
    import { Button } from 'cf-component-button';
    
    ReactDOM.render(
      <StyleProvider>
        <Button type="primary" onClick={() => console.log('clicked')}>
          Primary Button
        </Button>
      </StyleProvider>,
      document.getElementById('react-app')
    );