fluidattacks-designs 0.3.0

Fluid Attacks design system, GPUI variant: desktop widgets over the shared tokens
Documentation

designs / gpui

The desktop (GPUI) variant of the Fluid Attacks design system. The web variant in designs/src is the source of truth; this workspace projects its tokens and components onto gpui for Rust desktop apps (common/mrq today, signals when it migrates).

Layout

Follows the federated Rust standard (common/utils/rust):

  • crates/domain — fluidattacks-designs-domain: the design tokens and per-component styling decisions, pure and no_std, usable from any toolkit on any platform. Grows one component at a time; the web files each module mirrors are named in its docs.
  • crates/shell — fluidattacks-designs: the GPUI widgets over those tokens. macOS-gated with their toolkit for now, mirroring mrq (gpui's Linux build needs a native windowing stack the Linux CI runners don't carry).

Catalog

cargo run --example gallery opens the native component catalog (macOS). A browser gallery in the spirit of gpui-component's story-web (gpui compiled to wasm) is the intended long-term storybook equivalent; it stays out of scope until gpui's wasm backend ships in a crates.io release, because the federated cargo-deny policy pins all dependencies to crates.io (allow-git = []).

Fonts

nix build .#designs-gpui-fonts materializes the design system's faces (Roboto, Space Mono) hermetically, and the gpui dev shell exports the directory as FLUIDATTACKS_DESIGNS_FONTS for the gallery to read.

Delivering the faces is the app's job: Theme::init(mode, cx, faces) registers the bytes you hand it and reads no directory of its own. Bundling and signing font files is a packaging concern, and a library that resolved them from a path would force every consumer to reproduce this flake's environment. Pass &[] to accept the platform fallback.

Icons and illustrations

Glyphs are FontAwesome Pro, so they live neither in git nor in the nix store (whose cachix mirror is public) and cannot ship inside the published crate. Illustrations carry no such licence, but they are fetched rather than versioned, so they are absent from a checkout just the same. Assets resolves either from FLUIDATTACKS_DESIGNS_ICONS / FLUIDATTACKS_DESIGNS_IMAGES when those directories are present — the dev shell fetches the whole kit and the illustration list there — and otherwise from a table the app baked in at compile time.

To embed, a consuming app adds a build script:

fluidattacks_designs_domain::build::emit_assets(
    &[(Style::Solid, &["gear"])],
    &["integrates/empty/analyticsIcon"],
)?;

which fetches nothing itself: it copies bytes out of FLUIDATTACKS_DESIGNS_ICON_SRC and FLUIDATTACKS_DESIGNS_IMAGE_SRC, and fails loudly if an asset is absent. It always includes icon::REQUIRED_ICONS and empty_state::REQUIRED_IMAGES, the assets these components render themselves, so the widgets work without the app enumerating them. The result is a binary that needs no token, no network and no cache at runtime, which is what makes a relocatable signed bundle possible. A miss at runtime is an Err, not a blank square — so both kinds need embedding, not just glyphs.

Checks

Same jobs as every Rust component, from the designs flake:

  • nix run .#designs-gpui-lint — fmt, clippy, deny, machete
  • nix run .#designs-gpui-conformance — federated config drift check
  • nix run .#designs-gpui-test — nextest behind the coverage ratchet
  • nix develop .#gpui — the Rust dev shell