Skip to content

refactor(web_core): centralize layout mapping logic#1258

Open
ppazosp wants to merge 6 commits intogoogle:mainfrom
ppazosp:refactor/840-centralize-layout-mapping
Open

refactor(web_core): centralize layout mapping logic#1258
ppazosp wants to merge 6 commits intogoogle:mainfrom
ppazosp:refactor/840-centralize-layout-mapping

Conversation

@ppazosp
Copy link
Copy Markdown
Contributor

@ppazosp ppazosp commented Apr 22, 2026

Supersedes #1030, which was closed after I accidentally deleted my fork. Same head commit (850e87e), no content changes.

Description

Creates mapJustify() and mapAlign() functions in renderers/web_core/src/v0_9/common/layout.ts as the single source of truth for layout enum-to-CSS mapping.

  • Removes 6 duplicate implementations across React (basic + minimal), Lit (minimal), and Angular (basic) renderers
  • Fixes a bug in Angular where raw enum values (e.g., spaceBetween) were passed directly to CSS instead of being mapped to valid values (space-between)

Fixes #840

Pre-launch Checklist

ppazosp added 6 commits March 29, 2026 23:17
…eview

Moved mapJustify/mapAlign from common/ to basic_catalog/styles/ since they
are specific to basic catalog widgets (Row, Column, List), not protocol-level.
Updated consumer imports in react, lit, and angular to use
@a2ui/web_core/v0_9/basic_catalog.
Resolves conflicts introduced by:
- google#1079 (Lit) and google#1205 (React) — deleted the minimal catalog entirely,
  so our edits to minimal/{Row,Column} files are dropped.
- google#1166 (Angular) — introduced a new local JUSTIFY_MAP/ALIGN_MAP in
  angular/catalog/basic/utils.ts and used them inline in
  row.component.ts / column.component.ts. Since google#840's goal is to
  eliminate these duplicates, utils.ts is removed and the components
  now import mapJustify/mapAlign from @a2ui/web_core/v0_9/basic_catalog.
- web_core/basic_catalog/index.ts now re-exports both the new layout
  helpers and the injectBasicCatalogStyles helper from upstream.
…mappers

mapJustify/mapAlign previously coerced both undefined input and unknown
enum values into hardcoded defaults (flex-start / stretch). This caused
two silent regressions:

- Undefined props produced a concrete CSS value, overriding inherited
  styles and CSS-variable theming (breaks the --a2ui-*-gap pattern
  introduced in google#1166).
- Unknown enum values were swallowed, masking future spec additions or
  malformed agent output from the browser's styling pipeline.

Return undefined on nullish input so consumers leave the style unset.
Pass unknown values through unchanged so they stay visible. Matches
the pre-google#1030 Angular behavior documented in row.component.spec.ts
(align: 'baseline') and column.component.spec.ts ('missing justify
and align' case).

Tests updated in layout.test.ts; full suites still pass (web_core 273,
angular 229, react 443, lit 70).
- Use Map instead of Record<string, string> so prototype keys such as
  'toString' no longer resolve to inherited functions.
- Accept null alongside undefined in the parameter type; both return
  undefined so consumers leave the CSS property unset.
- Add 'baseline' as an explicit entry in alignMap (previously worked
  via passthrough). Documents it as a supported alignment value.
- Add tests for null input and the 'toString' prototype collision.
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request centralizes the layout mapping logic for justify-content and align-items by moving mapJustify and mapAlign into a shared web_core package. This change unifies the behavior across Angular and React renderers and includes new unit tests. Feedback suggests using ReadonlyMap for the internal mapping constants to enhance type safety.

Comment on lines +33 to +41
const justifyMap = new Map<string, string>([
['center', 'center'],
['end', 'flex-end'],
['spaceAround', 'space-around'],
['spaceBetween', 'space-between'],
['spaceEvenly', 'space-evenly'],
['start', 'flex-start'],
['stretch', 'stretch'],
]);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Using a Map is a good choice to avoid prototype chain lookups. To further improve type safety and prevent accidental mutations, consider marking the maps as ReadonlyMap and potentially using a union type for the keys if the A2UI layout enums are defined elsewhere in the codebase.

Suggested change
const justifyMap = new Map<string, string>([
['center', 'center'],
['end', 'flex-end'],
['spaceAround', 'space-around'],
['spaceBetween', 'space-between'],
['spaceEvenly', 'space-evenly'],
['start', 'flex-start'],
['stretch', 'stretch'],
]);
const justifyMap: ReadonlyMap<string, string> = new Map<string, string>([
['center', 'center'],
['end', 'flex-end'],
['spaceAround', 'space-around'],
['spaceBetween', 'space-between'],
['spaceEvenly', 'space-evenly'],
['start', 'flex-start'],
['stretch', 'stretch'],
]);

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

Labels

None yet

Projects

Status: Todo

Development

Successfully merging this pull request may close these issues.

Centralize Layout Mapping Logic

1 participant