Skip to main content

Button Token Mapping Challenges

This document provides detailed examples of the challenges in mapping ODS button tokens to Abyss button tokens, serving as a reference for the token conversion strategy outlined in adr-021-ods-to-abyss-token-conversion.

1. Compound Values vs. Split Values

Example:

  • ODS compound value example:
{
"component": "button",
"group": "options",
"category": "size",
"subcategory": "small",
"section": "container",
"property": "padding",
"value": "7px 16px" // Compound CSS value that needs splitting
}
  • Abyss: Requires mapping to two separate tokens:
    • button.spacing.padding.horizontal.container.sm: "{web.semantic.spacing.scale.lg}"
    • button.spacing.padding.vertical.container.sm: "{web.semantic.spacing.scale.xs}"

Challenge: The automation would need to:

  1. Recognize that "7px 16px" is a compound CSS shorthand
  2. Split it into vertical (7px) and horizontal (16px) values
  3. Map each to the corresponding Abyss token path

2. State Representation Differences

Example:

  • ODS uses explicit state and variant fields:
{
"component": "button",
"group": "themes",
"category": "light",
"variant": "primary", // Explicit variant field
"state": "hover", // Explicit state field
"section": "container",
"property": "background-color",
"value": "{ds.btnColors.themes.light.primary.hover.background.color.value}"
}
  • Abyss uses state as path segment: button.color.surface.container.filled-brand.rest
  • Abyss state values: rest (instead of "default"), hover, active, disabled

Challenge: The automation would need to:

  1. Map the state field values from ODS to the corresponding Abyss state path segments ("default" → "rest")
  2. Transform ODS variant field values to the Abyss variant-color combinations (e.g., ODS "primary" maps to Abyss "filled-brand")

3. Property and Section Organization

Example:

  • ODS property and section organization:
{
"component": "button",
"group": "themes",
"category": "light",
"variant": "primary",
"state": "default",
"section": "label", // Section field
"property": "font-color", // Property field
"value": "{ds.btnColors.themes.light.primary.default.font.color.value}"
}
  • Abyss: button.color.text.label.filled-brand.rest: "{web.semantic.color.text.on-container.neutral.default}"

Challenge: The automation would need to:

  1. Recognize that the "section" + "property" combination in ODS maps to different path structures in Abyss
  2. Understand that "section: label, property: font-color" corresponds to "text.label" category in Abyss
  3. Map the ODS variant field value ("primary") to the Abyss variant-color combination ("filled-brand")

4. Icon-Specific Properties

Example:

  • ODS has granular icon sections with specific properties for leading, trailing, and loading icons:
// ODS uses specific section types for different icon positions
{
"component": "button",
"group": "options",
"category": "size",
"subcategory": "large",
"section": "icon-leading", // Specific icon position
"property": "margin-right",
"value": "8px"
},
// Additional properties for the same icon section
{
"section": "icon-leading",
"property": "min-height",
"value": "24px"
}
  • Abyss groups icon properties differently:
    • "button.sizing.all.icon": "{web.semantic.sizing.icon.utility.xs}"
    • "button.sizing.all.icon-only.icon": "{web.semantic.sizing.icon.utility.md}"

Challenge: The automation would need to:

  1. Identify related icon properties across specific section types ("icon-leading", "icon-trailing", "icon-loading")
  2. Map between different organizational structures
  3. Handle cases where multiple ODS tokens map to a single Abyss token
  4. Distinguish between standard icon properties and icon-only button properties

5. Size Mapping Complexity

Example:

  • ODS defines size tokens with size information in the subcategory field:
// Small, medium, and large button heights
{
"component": "button",
"group": "options",
"category": "size",
"subcategory": "small", // Size in subcategory field
"section": "container",
"property": "min-height",
"value": "32px"
},
{ "subcategory": "medium", "property": "min-height", "value": "40px" },
{ "subcategory": "large", "property": "min-height", "value": "48px" }
  • Abyss:
    • "button.sizing.height.min.container.sm": "{web.semantic.sizing.height.min.sm}"
    • "button.sizing.height.min.container.md": "{web.semantic.sizing.height.min.md}"
    • "button.sizing.height.min.container.lg": "{web.semantic.sizing.height.min.lg}"

Challenge: The automation would need to:

  1. Extract the size value from the subcategory field
  2. Map between different size naming patterns ("small"/"medium"/"large" to "sm"/"md"/"lg")
  3. Handle the reorganized structure with "container" at a different level

6. Complex Variant System and Missing Counterparts

Example 1: Variant-Color Combinations

  • The Abyss button tokens combine variants with colors, requiring complex mapping:
    // Filled variant with brand color
    "button.color.text.label.filled-brand": "{web.semantic.color.text.label.cta.primary-alt}"
    // Outline variant with destructive color
    "button.color.text.label.outline-destructive": "{web.semantic.color.text.status.error}"
  • ODS uses separate paths for variants and colors

Example 2: Different Focus State Implementation

  • Abyss implements focus states through a utility function in the styling system:
    '&:focus-visible': {
    focusRing:'boundingBorder'
    }
  • ODS implements focus as explicit component tokens with multiple properties:
    // Structure tokens for focus properties
    {
    "component": "button",
    "group": "structure",
    "category": "focus",
    "section": "outline",
    "property": "offset",
    "value": "2px"
    },
    // Additional tokens for style and color
    { "property": "style", "value": "solid" },
    {
    "group": "themes",
    "category": "light",
    "variant": "focus",
    "section": "outline",
    "property": "color",
    "value": "#0C55B8"
    }

Example 3: Icon-Only Button Specifics

  • Abyss has specialized tokens for icon-only buttons with per-size values:
    "button.sizing.all.icon-only.container.sm": "{web.semantic.sizing.all.sm}"
    "button.sizing.all.icon-only.container.md": "{web.semantic.sizing.all.md}"
    "button.sizing.all.icon-only.container.lg": "{web.semantic.sizing.all.lg}"
  • ODS has icon tokens but organizes them differently with leading/trailing distinctions

Example 4: Loading State Support

  • Abyss button has specific loading spinner colors for different variants:
    "button.color.surface.loading-spinner.text-brand": "{web.semantic.color.surface.container.status.info.saturated}"
  • ODS has a general loading icon configuration

Challenge: The mapping process would need to:

  1. Identify missing token counterparts in ODS
  2. Map ODS variants to Abyss's combined variant-color system
  3. Create appropriate mappings for specialized token categories like loading states
  4. Document these gaps for future consideration in ODS token development

Conclusion

These examples from just the Button component illustrate the complexity of token mapping. These challenges reinforce why a purely automated approach would be insufficient. The mapping process requires value transformation, structural reorganization, and edge case handling that necessitates a hybrid approach with manual configuration of specialized transformers.

Table of Contents