elm-ui

repository·master·Indexed 23 days ago

https://github.com/mdgriffith/elm-ui

A design toolkit for the Elm programming language that provides a type-safe, explicit alternative to HTML and CSS. It allows developers to define layouts and styling directly within Elm code using functions like row, el, and text, and modules such as Element.Background, Element.Border, and Element.Font. The library focuses on error prevention, performance, and explicit styling, including support for accessibility markup via Element.Region and pseudo-classes for user interaction states.

Tokens
4.9K
Snippets
14
Records
31
Agent score
80%

What's inside elm-ui

  1. What is elm-ui?

    master

    elm-ui is a design toolkit for the Elm programming language that serves as a complete alternative to HTML and CSS. Instead of managing separate style sheets and HTML structures, you define your layout and styling explicitly within your Elm code.

    Key benefits include:

    • Simplified Layout: Drawing inspiration from design and typography domains rather than CSS implementation details.
    • Error Prevention: Many common CSS layout errors are impossible to express using the library's API.
    • Explicit Styling: Layout and style are defined in a central, easy-to-modify way within your Elm views.
    • Performance: Designed to run fast.
  2. Understand the rendering order of nearby elements

    master

    In elm-ui, elements can be positioned relative to their parent using 'nearby' modifiers. The rendering order is determined by when they are inserted into the DOM relative to the parent's other children:

    • behindContent: Rendered before the other children of the element. It sits between the element's background and its children.
    • below, above, onLeft, onRight, and inFront: Rendered after the other children of the element.

    This specific order allows inFront to work without requiring explicit z-index overrides, which improves GPU performance. It also ensures that inFront elements on higher-level DOM nodes appear on top of inFront elements on lower-level nodes.

  3. How color and alpha are separated in elm-ui

    master

    In elm-ui, the Color type is designed to be opaque (without an alpha channel). Transparency is treated as a separate property from the color's identity. This separation serves several purposes:

    1. Unified Color Type: Allows a single Color type to work across different contexts, such as WebGL, where transparency might be handled differently.
    2. Accessibility: Makes calculating color contrast for accessibility evaluation easier, as it avoids the need to emulate browser-based alpha mixing.
    3. Explicit Design: Encourages developers to use explicit color mixing functions (like Color.mix) rather than relying on alpha transparency to achieve visual effects like tinting or shading.

    Instead of modifying the alpha channel of a color, you use specific attributes to control opacity for fonts, backgrounds, and borders.

  4. How alignment works in rows and columns

    master

    Alignment in elm-ui applies to the element it is attached to, rather than its children.

    • On row or column: Alignment affects the position of the container itself.
    • On children: Alignment affects how that specific child is positioned within the parent. If an element is aligned (e.g., alignLeft or alignRight), it will push other elements aside.
    • Default Behavior: Elements are center (specifically centerX for horizontal) by default. All elements start with width/height shrink (the size of their contents).
  5. Use pseudo-classes for hover, focus, and active states

    master

    You can style elements based on user interaction using Element.mouseOver, Element.focused, and Element.mouseDown.

    Important Type Distinction:

    • Attribute msg: Standard attributes. These cannot be used inside pseudo-class functions.
    • Attr decorative msg: A special attribute type (Decorative Attributes) that can be used both as a normal attribute and within pseudo-class functions like mouseOver.

    Only a subset of properties are permitted within pseudo-classes; using unsupported properties will result in a compiler error.

  6. Determine layering behavior for nearby elements

    master

    When using nearby modifiers, the visual stacking order follows these rules:

    1. inFront: Renders in front of all children. If a child also has an inFront modifier, the parent's inFront element will still appear on top of the child's inFront element.
    2. behindContent: Renders between the element's background and its children.
    3. Directional modifiers (onLeft, onRight, above, below): These will render in front of any element they overlap with.
      • Conflict with inFront: If an element has an inFront modifier and its neighbor has an onLeft modifier, the onLeft element will appear on top of the inFront element.
    4. Overlapping directional modifiers: If onLeft, onRight, above, or below from different elements overlap, the source order (DOM order) determines the winner:
      • In a row, the element attached to the one farthest to the right wins.
      • In a column, the element attached to the one farthest down wins.
  7. Understanding directionality in elm-ui

    master

    Unlike CSS Flexbox, which often uses logical properties like flex-start or flex-end that adapt to text direction, elm-ui uses concrete directional properties such as alignLeft and alignRight.

    When building applications that need to support both Left-to-Right (LtR) and Right-to-Left (RtL) languages, developers must be aware that using concrete alignment properties will fix the element to a specific side regardless of the language direction. To support internationalization properly, you should consider how these concrete directions impact your layout when switching between LtR and RtL contexts.

  8. Run layout rendering tests locally

    master

    Layout testing ensures that layouts render correctly across browsers by rendering output and harvesting bounding boxes from the browser. These tests are located in elm-ui/tests-rendering/src/Tests.

    By default, running these locally uses headless Chrome, so no browser window will appear.

    npm install
    npm run test-render
    npm run test-render
  9. Run layout rendering tests on Sauce Labs

    master

    To automate layout testing using Sauce Labs, you must first create a elm-ui/sauce.env file containing your credentials:

    export SAUCE_ACCESS_KEY={your key}
    export SAUCE_USERNAME={your username}

    Once the environment file is configured, run the following command:

    npm run test-render-sauce

    Note: The compiled elm-ui test must be hosted at a public URL for Sauce Labs to access it.

  10. Run the Elm UI unit test suite

    master

    The standard unit tests for elm-ui are located in tests/suite/ and are executed using elm-test. To run them, ensure you are in the elm-ui root directory.

    # in the root elm-ui directory
    yarn install   # or npm install
    yarn run test  # or npm run test
    yarn run test
  11. Add a reproduction test case (Ellie) to the codebase

    master

    When a bug has an 'ellie' (reproduction case), follow these steps to add it to the codebase:

    1. Open a PR that copies the ellie into the tests-rendering/cases/open directory.
    2. Give the file a succinct, human-readable name.
    3. Rename all Element.* imports to Testable.Element.*.
    4. In the module comment, include a link to the issue, the issue title, and the issue body.

    Example file structure: tests-rendering/cases/open/YourFileName.elm

  12. Important setup note for browsers

    master
    When deploying an application using elm-ui, ensure that your HTML file includes <!DOCTYPE html> at the very top. Omitting this declaration may cause layout rendering issues in some web browsers.