Skill v1.0.1
currentAutomated scan96/100+3 new
version: "1.0.1" name: a1-migration description: 'Migrate an Angular application to the One Allianz (A1) Design System. Use when: migrating to A1 design system, applying One Allianz theme, migrating circle toggles to tiles, updating small stages, updating layout to left-alignment, A1 brand kit, ngx-brand-kit, ng-aquila migration, NDBX to A1.' argument-hint: 'Theme (optional): spacious | compact | dense' metadata: version: 0.1.4
A1 Design System Migration
When to Use
- Migrating an Angular app from NDBX/old design system to One Allianz (A1) Design System
- Applying One Allianz theme (
spacious,compact, ordense) - Replacing
nx-circle-toggle/nx-circle-toggle-groupwithnx-tile/nx-tile-group - Replacing info buttons with popovers to use the new
NxInfoIconComponent - Updating layout from center-aligned to left-aligned (A1 standard)
- Adjusting
nx-small-stagecomponents, eyebrows and accent-color headlines
How to Apply Changes
- if css is required, add to the component's CSS file. If the component is standalone, add the CSS to the component's
stylesarray in the@Componentdecorator. - write style definitions into components style file. Do not use inline styles in the HTML template.
IMPORTANT: Before starting, tell the user the skill version "0.1.4" and that it's in beta phase. This is important for tracking and future updates.
Step 1: Apply A1 Theme
Important: check if package @allianz/ngx-brand-kit is installed.
- if not installed, do not try to install, do not ask the user to install and skip this step and continue with Step 2.
- if installed, continue with the Procedure as described below.
Procedure
- If theme is not specified, ask the user which theme they want:
spacious,compact, ordense.
- spacious for end customer-facing apps with more white space and larger touch targets
- compact for internal tools and dashboards where more information density is needed
- dense for data-heavy applications where maximum information density is required (e.g. tables, analytics)
- Run the schematic from the project root (where
angular.jsonlives):
``bash ng g @allianz/ngx-brand-kit:apply-a1-theme --type=<THEME> ``
Step 2: Migrate Circle Toggles → Tiles
Stack: Angular standalone components, TypeScript, @allianz/ng-aquila
Imports
import { NxTileComponent, NxTileGroupComponent } from '@allianz/ng-aquila/tile';
If used in a Standalone Component, add the NxTileComponent, NxTileGroupComponent to the components imports array.
Decision Rules
| Scenario | Action | |
|---|---|---|
nx-circle-toggle not in a group | Multi-select → use nx-tile-group [value]="arrayOfValues" | |
nx-circle-toggle inside nx-circle-toggle-group | Single-select → use nx-tile-group [value]="selectedValue" | |
circleText attribute present | Remove it; add <!-- TODO: revisit once toggle-button component is available --> |
Selection / Forms Pattern
Before (checked-based):
<nx-circle-toggle-group><nx-circle-toggle[checked]="sel==='a'"value="a"label="Label A"icon="icon-name"></nx-circle-toggle><nx-circle-toggle[checked]="sel==='b'"value="b"label="Label B"icon="icon-name"></nx-circle-toggle></nx-circle-toggle-group>
After (value-based on group):
<nx-tile-group [value]="sel"><nx-tile value="a" label="Label A" icon="icon-name"></nx-tile><nx-tile value="b" label="Label B" icon="icon-name"></nx-tile></nx-tile-group>
IMPORTANT: Do NOT put content inside<nx-tile>. Use onlylabel,value, andiconattributes.
Layout Rules
| Layout found | What to do | |
|---|---|---|
| No wrapper, no layout CSS | Replace group directly; no extra layout needed | |
nxLayout / nxRow / nxCol grid | Derive maxColumns from lowest nxCol number: 12 ÷ lowest = maxColumns. Remove grid wrapper. | |
| Custom CSS | Translate to [maxColumns] on nx-tile-group; copy CSS only if auto-grid is insufficient | |
| 2–3 tiles total | Wrap nx-tile-group in nxCol="12,12,6" (half-width) |
For each occurrence found, output a short decision log: what was there, what you chose and why.
Step 3: Migrate Info Popups → new Info Icon Component
- Identify info buttons with popups: look for buttons (e.g. buttons with directive
nxPopoverTrigger) that trigger popovers and just have an info icon inside. - Replace with `NxInfoIconComponent`: use the new component for consistent styling and behavior.
- Example:
<nx-info-iconnxFormfieldAppendixbuttonAriaLabel="Additional information"popoverDirection="bottom"popoverWidth="300px"><span>This is an info icon with a popover. Click the icon to see additional information. Sadipscingelitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diamvoluptua.</span></nx-info-icon>
And the corresponding import:
import { NxInfoIconComponent } from '@allianz/ng-aquila/info-icon';
If used in a Standalone Component, add the NxInfoIconComponent to the components imports array.
- Important: Do not change buttons inside Formfields (
<nx-formfield>). Only replace standalone info buttons that trigger popovers.
Step 4: Update Layout — Left Alignment
A1 uses left-alignment throughout for accessibility and consistency.
Checklist
- Remove centering on rows: Change or remove
rowJustify="center"→ userowJustify="start"or remove entirely. - Remove text centering: Remove
class="text-center",style="text-align: center", and similar on headings and paragraphs. - Bottom navigation buttons (Back / Next):
- Must be right-aligned (
rowJustify="end") - Must be side-by-side (same
nxRow, not stacked in separate rows) - Must use sentence case ("Back", "Next") not ALL CAPS
nxColonly accepts numbers — warningnxCol="auto"will break; usenxCol="12",nxCol="12,12,6"or similar- info on
nxCol: breakpoints are defined asnxCol="<tiny>, <small>, <medium>, <large>, <xlarge>, <2xlarge>, <3xlarge>" - must be vertically centered within the row — if
nxRowis used, addrowAlignItems="center".
- Margins / padding: Remove
margin: auto, horizontal centering, and ensure content aligns to the left edge.
Vertical Spacing Adjustments
- Important: Skip this step if the
ngx-brand-kitis not installed and continue withHeadline Sizesbelow. The spacing values below rely on CSS variables from the A1 brand kit, so if it's not installed, leave spacing as-is. - Find Dividers (
<hr>,nx-divider,nxCol="12" class="section-divider"or similar) divider lines that span the full width of the page and add vertical spacing above and below them. Usevar(--semantic-gap-all-static-1600)for this spacing to ensure consistency with A1 design standards. - Headlines that are used standalone (outside of other components) should have a spacing below them. Use the mapping below
nxHeadline size="3xl"→var(--semantic-gap-all-static-1200)nxHeadline size="2xl"→var(--semantic-gap-all-static-1000)nxHeadline size="xl"→var(--semantic-gap-all-static-800)- If the element underneath the headline has a top spacing (e.g.
margin-toporpadding-top), remove it to avoid double spacing or subtract the headline spacing from it.
Headline Sizes
Hierarchy rule — applies after the mapping table and overrides it where needed: The mapping table below is a starting point, not a final answer. After applying it, verify that the resulting sizes form a clear visual hierarchy on the page. If a primary section heading (e.g. an <h2> that is the main title of a page section) maps to a small size like s or m, override the mapped value to restore the hierarchy. A page with an h1 at size="3xl" should use size="2xl" for its primary h2 sections, size="xl" for sub-sections, and so on — regardless of what the old assignment was.
- if you find
nxHeadlinewith type assignments (e.g.<h1 nxHeadline="page">), translate tosizeattribute. For example,<h1 nxHeadline="page">becomes<h1 nxHeadline size="3xl">. Ensure the main headline innx-small-stageusessize="3xl"for A1 consistency.
| old assignment | size attribute | use for | |
|---|---|---|---|
| nxHeadline="page-bold-caps" | nxHeadline size="4xl" | huge page headlines, only for marketing pages, not for product UIs | |
| nxHeadline="page" | nxHeadline size="3xl" | main page headlines | |
| nxHeadline="section" | nxHeadline size="2xl" | section headlines | |
| nxHeadline="subsection-large" | nxHeadline size="xl" | large subsection headlines | |
| nxHeadline="subsection-medium" | nxHeadline size="l" | medium subsection headlines | |
| nxHeadline="subsection-small" | nxHeadline size="m" | small subsection headlines | |
| nxHeadline="subsection-xsmall" | nxHeadline size="s" | extra small subsection headlines |
After applying the table, check: does the result make sense in context? A primary <h2> section heading should never end up at size="s" just because the old code used subsection-xsmall. Promote it to the correct level in the page hierarchy.
Step 5: Adjust Small Stages
5.1 Subline → Eyebrow
Move any <p nxCopytext="large">Subline</p> inside nx-small-stage to an eyebrow above the <h1>:
<nx-eyebrow size="s">Subline Text</nx-eyebrow><h1 nxHeadline size="3xl">...</h1>
Use the size="s" eyebrow size for nxHeadline size 3xl and smaller. If the user wants a nxHeadline larger than 3xl, use size="m" for the eyebrow.
import { NxEyebrowComponent } from '@allianz/ng-aquila/eyebrow';
If used in a Standalone Component, add the NxEyebrowComponent to the components imports array.
5.2 Partial Headline Coloring (required)
Always wrap the most meaningful word or short phrase in the <h1> with an accent-color span. This is a required A1 design standard for nx-small-stage headlines — do not skip it. Choose the word or phrase that carries the most semantic weight (the product, the action, or the subject — not filler words like "your" or "and").
<h1 nxHeadline size="3xl">Enter your <span [nx-accent-color]="'aqua'">property details</span></h1>
import { NxAccentColorComponent } from '@allianz/ng-aquila/text';
If used in a Standalone Component, add the NxAccentColorComponent to the components imports array.
5.3 Headline Size
- remove assignments to
nxHeadlinein HTML headline elements (e.g.<h1 nxHeadline="page">) and replace with<h1 nxHeadline size="3xl">for all small stage headlines. Ensure the main headline innx-small-stageusessize="3xl"for A1 consistency.
Step 6: Migrate Context Menu Selection
nxContextMenuItem now has built-in single/multi selection. Hand-rolled patterns that combine selectable, a <nx-icon name="check">, an explicit role="menuitemradio|menuitemcheckbox" and [attr.aria-checked] should be migrated to the new API.
Detection
Look for nxContextMenuItem usages that match any of these signals:
selectable(bare attribute) plus a manual<nx-icon name="check">rendered conditionally on the selected value.role="menuitemradio"orrole="menuitemcheckbox"set by hand on a menu item.[attr.aria-checked]bound by hand on a menu item.
Replacement
Before:
<buttonnxContextMenuItemselectabletype="button"(click)="selectedLanguage = o.value"role="menuitemradio"[attr.aria-checked]="selectedLanguage === o.value ? 'true' : 'false'">@if (selectedLanguage === o.value) {<nx-icon aria-hidden="true" name="check" nxIconPositionStart></nx-icon>}{{ o.label }}</button>
After:
<buttonnxContextMenuItemselectable="single"[selected]="selectedLanguage === o.value"type="button"(click)="selectedLanguage = o.value">{{ o.label }}</button>
For multi-select menus use selectable="multi" and keep disableCloseOnSelect if the menu should stay open between toggles. Drop any manual <nx-icon name="check">, role, and [attr.aria-checked] bindings — the component renders the indicator and sets the role for you.
Notes
- Legacy
selectablewithout a value still works and is treated as"true". but this is a legacy behavior. This is a behavior change vs. older versions where the bare attribute only adjusted padding; templates relying on the old purely-stylistic behavior should set[selectable]="null"(or remove the attribute) if they don't want a radio role. - After applying this step, append
"context-menu-selection"to thea1Migration.stepsarray inpackage.json.
Migration Tracking
After completing each step, record the migration so adoption can be tracked across teams via GitHub search.
Project-level metadata in package.json
After Step 1 (theme applied), add an a1Migration key to package.json. After each subsequent step completes, append the step name to the steps array:
"a1Migration": {"skillVersion": "0.1.4","appliedAt": "YYYY-MM-DD","theme": "<spacious|compact|dense>","steps": ["theme"]}
Append step names as they complete: "theme", "tiles", "info-icons", "layout", "small-stage", "context-menu-selection".
A fully migrated project looks like:
"a1Migration": {"skillVersion": "0.1.4","appliedAt": "YYYY-MM-DD","theme": "<spacious|compact|dense>","steps": ["theme", "tiles", "info-icons", "layout", "small-stage"]}
tracking of additional migration runs
If package.json already has an a1Migration key, add the steps to the array for steps that ran in the current session.