Primer ViewComponents

repository·main·Indexed 20 days ago

https://github.com/primer/view_components

A library of Ruby ViewComponents implementing the Primer Design System for Ruby on Rails applications. It provides GitHub-style UI components, including tools for component scaffolding via `component_generator`, lifecycle management (alpha, beta, stable), and support for client-side behaviors using Catalyst and the Rails Asset Pipeline or npm.

Tokens
9.3K
Snippets
29
Records
47
Agent score
69%

What's inside primer-view_components

  1. Documentation and Lookbook deployment

    main

    The documentation site and Lookbook are automatically deployed via GitHub Action workflows whenever changes are merged into the main branch.

    • Documentation Site: Deployed via GitHub Pages (aliased from https://primer.github.io/view_components/).
    • Lookbook: Deployed to Azure because it requires a live Rails server (aliased from https://view-components-storybook.eastus.cloudapp.azure.com).
  2. Understand the component lifecycle and experimental process

    main

    Components in Primer ViewComponents follow a lifecycle of alpha, beta, and stable.

    To upstream a new component, it is recommended to follow this experimental workflow:

    1. Develop in a draft PR: Use a Primer ViewComponents draft pull request as a sandbox for initial exploration, testing, and documentation.
    2. Validate in production: Copy the component to a production application using the Primer::Experimental namespace. Integrate it into at least three different locations to validate technical decisions and iterate on the API.
    3. Open a formal PR: Once validated in production and meeting all criteria (Design Infrastructure approval, CSS availability, production usage, and API consistency), open a pull request to add it to the main Primer ViewComponents repository.
  3. How Primer ViewComponents linters are structured

    main

    The linting system is designed to help migrate HTML to components using three main architectural pieces:

    • BaseLinter: The core class that interprets the AST and builds a "tag tree" to link opening and closing tags. This allows for applying autocorrections using do/end blocks.
    • Autocorrectable: A module providing logic to transform HTML attributes into component arguments and build replacement code.
    • ArgumentMappers: Classes that define how specific attributes and classes are converted into component arguments. They inherit from ERBLint::Linters::ArgumentMappers::Base and ensure compatibility with SystemArguments during autocorrections.
  4. How component CSS is managed in Primer View Components

    main

    To reduce development overhead and synchronization issues between libraries, all new View Components include their corresponding CSS directly within the primer/view_components repository rather than in primer/css.

    This approach ensures that component logic (Ruby) and component styling (CSS) are developed together. The CSS is built using PostCSS with the preset-env plugin, enabling modern CSS features like nested selectors, match functions, and container queries.

    Integration Options

    When consuming these styles in a production bundle, there are two primary patterns:

    1. Main Bundle Import: Including the compiled CSS file directly in your main stylesheet via: @import "@primer/view-components/app/assets/styles/primer_view_components.css";
    2. Dynamic Loading (CSS Modules): Loading specific bundles for each component dynamically when the component is rendered on a page (planned/advanced usage).
    /* Example of including the component styles in your main bundle */
    @import "@primer/view-components/app/assets/styles/primer_view_components.css";
  5. How the release process works with Changesets

    main

    The project uses Changesets to manage versioning (semver) and changelogs.

    Workflow Summary

    1. Add a Changeset: When contributing, add a changeset file to your pull request branch (not main). The changeset-bot will prompt you on new PRs. This file defines the changelog entry.
    2. Merge to Main: Once your PR is approved and merged into main, the Changesets action automatically generates a new Release pull request.
    3. Publish: When maintainers merge the Release pull request, Changesets automatically:
      • Creates a GitHub release.
      • Publishes the new version of the Ruby gem.
      • Publishes the new version of the npm package.

    Versioning Note

    The project follows semantic versioning (semver), but because it is currently pre-v1, every release is treated as a patch release and may contain breaking changes.

  6. Author client-side behaviours using Catalyst

    main

    Primer ViewComponents uses Catalyst for implementing client-side behaviours within components. When creating new Primer ViewComponent behaviours, you should author them using Catalyst to maintain consistency with the GitHub codebase and to simplify the migration of components from GitHub to Primer ViewComponents.

    Note that using Catalyst increases the Primer ViewComponents JavaScript bundle size by approximately 1kb.

  7. Implement a custom ArgumentMapper

    main

    ArgumentMappers transform HTML elements into component arguments. All mappers must inherit from ERBLint::Linters::ArgumentMappers::Base. By default, the base class handles:

    1. classes $\rightarrow$ SystemArguments
    2. aria-* attributes
    3. data-* attributes
    4. test_selector
    5. HTML tag $\rightarrow$ tag:

    Customizing attribute and class mapping

    If you need custom logic, implement these methods in your subclass:

    attribute_to_args

    Define a list of attributes in an ATTRIBUTES constant. Implement attribute_to_args to return a hash of arguments for each attribute.

    classes_to_args

    Implement this method to receive a list of classes and return a Hash of arguments. The hash must include a classes key containing any classes that were not mapped (or an empty array).

  8. Styling principles for Primer ViewComponents

    main

    Styling in Primer ViewComponents follows a strict mapping to Primer CSS.

    Key Rules:

    • No Inline Styles: Do not use inline styles within components.
    • No Direct Utility Classes: Avoid using Primer CSS utility classes directly for component styling.
    • 1:1 Mapping: There should be a 1:1 mapping between a Primer ViewComponent and its corresponding component class in Primer CSS.
    • Local Styles: Most components define their specific styles in .pcss files located adjacent to the component's Ruby code.
  9. Setup for local development

    main

    To set up the Primer ViewComponents repository for local development, follow these steps:

    1. Clone the repository: git@github.com:primer/view_components.git.
    2. Install Overmind.
    3. Run the setup script to install dependencies: script/setup.
    4. Start the development environment: script/dev. This will launch Lookbook on localhost:4000.
    git clone git@github.com:primer/view_components.git
    # Install Overmind first
    script/setup
    script/dev
  10. Scaffold a new component using the component generator

    main

    To create a new component, use the component_generator Thor task. This scaffolds the component logic, templates, and tests according to the specified status.

    Usage:

    bundle exec thor component_generator <component_name>

    Flags:

    • --status=[alpha|beta|stable]: Sets the component's lifecycle status (defaults to alpha).
    • --inline: Instead of generating an .html.erb template, it creates a #call method within the component class.
    • --js=<npm_package_name>: If provided, generates additional TypeScript and system test files for components with JavaScript dependencies.
  11. Determine the version type for a pull request

    main

    When contributing to primer/view_components, use Semantic Versioning (SemVer) to categorize your changes. Use the following criteria to decide if a change is Major, Minor, or Patch:

    Major

    Use a Major version bump for breaking changes, specifically:

    • Removing or renaming component names.
    • Removing or renaming component arguments.
    • Removing or renaming component slots.
    • Note: This applies to both Ruby and JavaScript code.

    Minor

    Use a Minor version bump for non-breaking feature changes or structural changes that don't break the API, specifically:

    • Changing the HTML output of a component.
    • Changing the CSS classnames of a component.
    • Removing dependencies from primer_view_components.gemspec or package.json.

    Patch

    Use a Patch version bump for maintenance and bug fixes, specifically:

    • Updating dependency versions.