Skip to content

Utility scale tokens (z-index, opacity, shadow, flex, gap) #307

Description

@ethangardner

Phase

Phase 1 — Complete the primitive tier

Prerequisite

Blocked by #287 (tier-first directory restructure) only.

Concern

Create tokens/system/ source files for the utility-scale property tokens — a group of primitive-tier tokens that originate from USWDS core's $system-properties nested Sass map rather than its simple flat maps.

Scope:

  • z-index: auto, bottom (-100), 0, 100–500, top (99999)
  • opacity: 0–100 (maps to 0.0–1.0)
  • shadow: box-shadow none + 1–5 (multi-part values with rgba())
  • flex: flex 1–12, fill, auto; flex-direction (row, column); flex-wrap (wrap, nowrap); order first (-1), last (999), 0–11, initial
  • gap: column-gaps 0, 1–6, 2px, 05; named aliases sm (→ 2px), md (→ 2), lg (→ 3)

Note: letter-spacing and per-typeface line-height (also sourced from $system-properties) are covered by the typography-sources issue (#305), not this one.

Files touched

  • New tokens/system/z-index/z-index.json
  • New tokens/system/opacity/opacity.json
  • New tokens/system/shadow/shadow.json
  • New tokens/system/flex/flex.json
  • New tokens/system/gap/gap.json
  • Modify tokens/index.js — register new groups
  • Modify config/style-dictionary.config.js — add output files for new groups
  • New build/css/system/{z-index,opacity,shadow,flex,gap}.css etc.

Implementation steps

1. tokens/system/z-index/z-index.json

{
    "z-index": {
        "$type": "number",
        "bottom": { "$value": -100, "$extensions": { "uswds": { "tier": "system", "legacyName": { "publicVar": "$system-z-index-bottom" } } } },
        "0":      { "$value": 0,    "$extensions": { "uswds": { "tier": "system", "legacyName": { "publicVar": "$system-z-index-0" } } } },
        "100":    { "$value": 100,  "$extensions": { "uswds": { "tier": "system", "legacyName": { "publicVar": "$system-z-index-100" } } } },
        "200":    { "$value": 200,  "$extensions": { "uswds": { "tier": "system", "legacyName": { "publicVar": "$system-z-index-200" } } } },
        "300":    { "$value": 300,  "$extensions": { "uswds": { "tier": "system", "legacyName": { "publicVar": "$system-z-index-300" } } } },
        "400":    { "$value": 400,  "$extensions": { "uswds": { "tier": "system", "legacyName": { "publicVar": "$system-z-index-400" } } } },
        "500":    { "$value": 500,  "$extensions": { "uswds": { "tier": "system", "legacyName": { "publicVar": "$system-z-index-500" } } } },
        "top":    { "$value": 99999,"$extensions": { "uswds": { "tier": "system", "legacyName": { "publicVar": "$system-z-index-top" } } } },
        "auto":   { "$value": "auto","$extensions": { "uswds": { "tier": "system", "legacyName": { "publicVar": "$system-z-index-auto" } } } }
    }
}

Note: bottom (-100) and top (99999) resolve to literal numeric values — not a separate naming convention.

2. tokens/system/opacity/opacity.json — 11 entries (0, 10, 20 … 100), values mapped n/100

{
  "opacity": {
    "$type": "number",
    "0":   { "$value": 0,   "$extensions": { "uswds": { "tier": "system", "legacyName": { "publicVar": "$system-opacity-0" } } } },
    "10":  { "$value": 0.1, "$extensions": { "uswds": { "tier": "system", "legacyName": { "publicVar": "$system-opacity-10" } } } },
    "100": { "$value": 1,   "$extensions": { "uswds": { "tier": "system", "legacyName": { "publicVar": "$system-opacity-100" } } } }
  }
}

Continue this pattern for 20 through 90 in increments of 10 (values 0.2 through 0.9).

3. tokens/system/shadow/shadow.json — 6 entries

Box-shadow values from USWDS core's properties map contain rgba() — author as $type: "string" with the full CSS value literal (avoids Style Dictionary's shadow composite transform complexity for a first pass):

{
    "shadow": {
        "$type": "string",
        "none": { "$value": "none", "$extensions": { "uswds": { "tier": "system", "legacyName": { "publicVar": "$system-box-shadow-none" } } } },
        "1": { "$value": "0 1px 0.25rem 0 rgba(0, 0, 0, 0.1)", "$extensions": { "uswds": { "tier": "system", "legacyName": { "publicVar": "$system-box-shadow-1" } } } },
        "2": { "$value": "0 0.25rem 0.5rem 0 rgba(0, 0, 0, 0.1)", "$extensions": { "uswds": { "tier": "system", "legacyName": { "publicVar": "$system-box-shadow-2" } } } },
        "3": { "$value": "0 0.5rem 1rem 0 rgba(0, 0, 0, 0.1)", "$extensions": { "uswds": { "tier": "system", "legacyName": { "publicVar": "$system-box-shadow-3" } } } },
        "4": { "$value": "0 0.75rem 1.5rem 0 rgba(0, 0, 0, 0.1)", "$extensions": { "uswds": { "tier": "system", "legacyName": { "publicVar": "$system-box-shadow-4" } } } },
        "5": { "$value": "0 1rem 2rem 0 rgba(0, 0, 0, 0.1)", "$extensions": { "uswds": { "tier": "system", "legacyName": { "publicVar": "$system-box-shadow-5" } } } }
    }
}

4. tokens/system/flex/flex.json — four sub-groups

flex, flex-direction, flex-wrap, order:

{
  "flex": {
    "$type": "string",
    "1":    { "$value": "1 1 0%",    "$extensions": { "uswds": { "tier": "system", "legacyName": { "publicVar": "$system-flex-1" } } } },
    "12":   { "$value": "12 1 0%",   "$extensions": { "uswds": { "tier": "system", "legacyName": { "publicVar": "$system-flex-12" } } } },
    "fill": { "$value": "1 1 0%",    "$extensions": { "uswds": { "tier": "system", "legacyName": { "publicVar": "$system-flex-fill" } } } },
    "auto": { "$value": "0 1 auto",  "$extensions": { "uswds": { "tier": "system", "legacyName": { "publicVar": "$system-flex-auto" } } } }
  },
  "flex-direction": {
    "row":    { "$value": "row",    "$extensions": { "uswds": { "tier": "system", "legacyName": { "publicVar": "$system-flex-direction-row" } } } },
    "column": { "$value": "column", "$extensions": { "uswds": { "tier": "system", "legacyName": { "publicVar": "$system-flex-direction-column" } } } }
  },
  "flex-wrap": {
    "wrap":    { "$value": "wrap",   "$extensions": { "uswds": { "tier": "system", "legacyName": { "publicVar": "$system-flex-wrap-wrap" } } } },
    "no-wrap": { "$value": "nowrap", "$extensions": { "uswds": { "tier": "system", "legacyName": { "publicVar": "$system-flex-wrap-no-wrap" } } } }
  },
  "order": {
    "first":   { "$value": -1,        "$extensions": { "uswds": { "tier": "system", "legacyName": { "publicVar": "$system-order-first" } } } },
    "0":       { "$value": 0,         "$extensions": { "uswds": { "tier": "system", "legacyName": { "publicVar": "$system-order-0" } } } },
    "11":      { "$value": 11,        "$extensions": { "uswds": { "tier": "system", "legacyName": { "publicVar": "$system-order-11" } } } },
    "last":    { "$value": 999,       "$extensions": { "uswds": { "tier": "system", "legacyName": { "publicVar": "$system-order-last" } } } },
    "initial": { "$value": "initial", "$extensions": { "uswds": { "tier": "system", "legacyName": { "publicVar": "$system-order-initial" } } } }
  }
}

Fill out flex entries 2 through 11 following the "N 1 0%" pattern, and order entries 1 through 10 as plain integers. order.first (-1) and order.last (999) resolve to literal values, not a separate naming convention.

5. tokens/system/gap/gap.json

Numeric gaps aliased into spacing where they correspond (sm → {gap.2px}, md → {gap.2}, lg → {gap.3}):

{
    "gap": {
        "$type": "dimension",
        "0":   { "$value": { "value": 0, "unit": "" }, "$extensions": { "uswds": { "tier": "system", "legacyName": { "publicVar": "$system-gap-0" } } } },
        "2px": { "$value": { "value": 2, "unit": "px" }, "$extensions": { "uswds": { "tier": "system", "legacyName": { "publicVar": "$system-gap-2px" } } } },
        "05":  { "$value": "{spacing.05}", "$extensions": { "uswds": { "tier": "system", "legacyName": { "publicVar": "$system-gap-05" } } } },
        "1":   { "$value": "{spacing.1}", "$extensions": { "uswds": { "tier": "system", "legacyName": { "publicVar": "$system-gap-1" } } } },
        "2":   { "$value": "{spacing.2}", "$extensions": { "uswds": { "tier": "system", "legacyName": { "publicVar": "$system-gap-2" } } } },
        "3":   { "$value": "{spacing.3}", "$extensions": { "uswds": { "tier": "system", "legacyName": { "publicVar": "$system-gap-3" } } } },
        "4":   { "$value": "{spacing.4}", "$extensions": { "uswds": { "tier": "system", "legacyName": { "publicVar": "$system-gap-4" } } } },
        "5":   { "$value": "{spacing.5}", "$extensions": { "uswds": { "tier": "system", "legacyName": { "publicVar": "$system-gap-5" } } } },
        "6":   { "$value": "{spacing.6}", "$extensions": { "uswds": { "tier": "system", "legacyName": { "publicVar": "$system-gap-6" } } } },
        "sm":  { "$value": "{gap.2px}", "$extensions": { "uswds": { "tier": "system", "legacyName": { "publicVar": "$system-gap-sm" } } } },
        "md":  { "$value": "{gap.2}", "$extensions": { "uswds": { "tier": "system", "legacyName": { "publicVar": "$system-gap-md" } } } },
        "lg":  { "$value": "{gap.3}", "$extensions": { "uswds": { "tier": "system", "legacyName": { "publicVar": "$system-gap-lg" } } } }
    }
}

Gap numeric values alias spacing where possible so a spacing change propagates. Note: the aliases {spacing.05} through {spacing.6} require the spacing tokens added in #304 to exist. If #304 hasn't merged yet when you pick this issue up, coordinate merge order or use the literal grid-base × m rem values directly as a stopgap and switch to aliases once #304 lands.

6. Update tokens/index.js and config/style-dictionary.config.js

Register system/z-index, system/opacity, system/shadow, system/flex, system/gap as new source groups / output files.

7. Run build

npm run build:tokens

Done when

  • npm run build:tokens exits 0
  • npm test exits 0
  • z-index: 9 entries (including bottom: -100 and top: 99999) in built output
  • opacity: 11 entries (0 through 100, values 0.0–1.0) in built output
  • shadow: 6 entries (none + 1–5) in built output; rgba() values intact
  • flex: 14 flex values (1–12, fill, auto) + 2 flex-direction + 2 flex-wrap + 15 order entries (first, 0–11, last, initial) in built output
  • gap: 12 entries (0, 2px, 05, 1–6, sm, md, lg) in built output; aliased values resolve correctly
  • order.first resolves to -1 and order.last to 999 in built output (literal negatives, not a naming convention)
  • build/ output committed alongside source changes

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Package: TokensWork affecting Tokens. Apply only when this area helps route or find the issue.

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions