ui-translation
Skill: UI Translation
Purpose
Translate natural language UI descriptions into IDS (Iress Design System) component implementations using @iress-oss/ids-components and @iress-oss/ids-tokens.
Translation Workflow
- Identify the UI elements — Break the description into components: actions (buttons), inputs (fields), layout (stacks, grids), content (text, cards), overlays (modals, slideouts), navigation
- Map to IDS components — Use the component mapping to find the right IDS component for each element
- Apply layout — Wrap elements in
IressStack(vertical),IressInline(horizontal), orIressRow/IressCol(grid). Always make grids responsive withspan={{ xs: 12, md: ... }} - Add responsive behaviour — Even if the description only mentions desktop, stack columns on mobile and relocate secondary content to
IressSlideoutor collapsible sections - Apply styling — Use styling props for spacing, colour, and typography. Use spacing tokens (0–10) for
gapprops - Verify output — Check that all imports resolve, no raw HTML is used where IDS components exist, grid layouts use responsive
spanvalues, and no common anti-patterns are present (disabled buttons, slot attributes, redundant textStyle)
Setup
Important: IDS v6 is currently in alpha. Install with the
@alphatag:npm install @iress-oss/ids-components@alpha # If using tokens directly: npm install @iress-oss/ids-tokens@alpha
import '@iress-oss/ids-components/dist/style.css'; // Required — component styles
import '@iress-oss/ids-tokens/build/css-vars.css'; // Required if using tokens directly
import {
IressProvider,
IressButton,
IressInput,
IressField,
IressStack,
IressInline,
IressText,
IressCard,
// ... import what you need
} from '@iress-oss/ids-components';
// Wrap your app in IressProvider (handles fonts + CSS variables)
function App() {
return <IressProvider>{/* your UI */}</IressProvider>;
}
Component Mapping
When you need to find the right IDS component for a UI element, read references/component-mapping.md for the full description → IDS component mapping tables (actions, form inputs, layout, content, overlays, navigation, tables).
Styling Props
When you need to apply spacing, colour, visibility, or typography props, read references/styling-props.md for the full IressCSSProps reference and accepted values.
Responsive Layout
Always produce responsive output. Even when the UI description only mentions a desktop layout, every translation should adapt to smaller screens. IDS uses a 12-column grid with 6 breakpoints (xs, sm, md, lg, xl, xxl).
Responsive Design Principles
Apply these when translating any UI description:
- Identify the primary task — What is the user trying to accomplish? The mobile layout should focus on this task and push everything else to secondary access points.
- Stack multi-column layouts — Side-by-side columns should stack to full-width on mobile (
span={{ xs: 12, md: ... }}). - Relocate secondary content — Move supplementary UI (filters, sidebars, metadata panels, secondary actions) into an
IressSlideout,IressModal, or collapsible section on mobile. - Simplify dense layouts — For tables with many columns or multi-panel dashboards, hide non-essential columns with
hideBelow, collapse sections, or switch to a card-based layout usinguseBreakpoint. - Preserve all functionality — Never remove features on mobile. Use
IressSlideout,IressModal, expandable sections, orIressTabSetto keep functionality accessible without cluttering the view.
Responsive Props
Many props accept a single value or an object keyed by breakpoint:
// Full-width on mobile, half on medium+
<IressCol span={{ xs: 12, md: 6 }} />
// Tighter gap on mobile, larger on desktop
<IressRow gutter={{ xs: 'sm', md: 'lg' }} />
Props that support responsive values: span, offset, gap, gutter, rowGap, p, px, py, m, mx, my, width, and all directional margin/padding props.
Responsive Visibility
Use hideFrom/hideBelow CSS props directly on any component:
<IressButton hideBelow="md">Desktop action</IressButton>
<IressText hideFrom="lg">Mobile only text</IressText>
For conditional rendering based on breakpoint (e.g. rendering entirely different components), use the useBreakpoint hook:
import { useBreakpoint } from '@iress-oss/ids-components';
function Navigation() {
const { breakpoint } = useBreakpoint();
const isMobile = breakpoint === 'xs' || breakpoint === 'sm';
return isMobile ? <MobileNav /> : <DesktopNav />;
}
Translation Examples
"A login form with email and password fields and a submit button"
import {
IressButton,
IressField,
IressInput,
IressStack,
} from '@iress-oss/ids-components';
function LoginForm() {
return (
<IressStack gap="4">
<IressField label="Email" htmlFor="email" required>
<IressInput id="email" type="email" placeholder="Enter your email" />
</IressField>
<IressField label="Password" htmlFor="password" required>
<IressInput
id="password"
type="password"
placeholder="Enter your password"
/>
</IressField>
<IressButton mode="primary" type="submit">
Log in
</IressButton>
</IressStack>
);
}
"A card with a title, description, and two action buttons"
import {
IressCard,
IressButton,
IressInline,
IressText,
} from '@iress-oss/ids-components';
function ActionCard() {
return (
<IressCard>
<IressCard.Header>
<IressText element="h3">Card Title</IressText>
</IressCard.Header>
<IressCard.Body>
<IressText>
This is the card description with supporting details.
</IressText>
</IressCard.Body>
<IressCard.Footer>
<IressInline gap="2">
<IressButton mode="primary">Confirm</IressButton>
<IressButton mode="secondary">Cancel</IressButton>
</IressInline>
</IressCard.Footer>
</IressCard>
);
}
"A settings page with a toggle, some checkboxes, and a save button"
import {
IressStack,
IressToggle,
IressCheckboxGroup,
IressCheckbox,
IressButton,
IressText,
IressDivider,
} from '@iress-oss/ids-components';
function SettingsPage() {
return (
<IressStack gap="6">
<IressText element="h2">Settings</IressText>
<IressToggle label="Enable notifications" />
<IressDivider />
<IressCheckboxGroup label="Notification types">
<IressCheckbox label="Email" value="email" />
<IressCheckbox label="SMS" value="sms" />
<IressCheckbox label="Push" value="push" />
</IressCheckboxGroup>
<IressDivider />
<IressButton mode="primary">Save settings</IressButton>
</IressStack>
);
}
"A dashboard with a sidebar and main content area"
Note: even though the description doesn't mention mobile, the sidebar is secondary content — on mobile it should move into a slideout so the main content gets focus.
import {
useState,
IressRow,
IressCol,
IressStack,
IressText,
IressCard,
IressButton,
IressSlideout,
useBreakpoint,
} from '@iress-oss/ids-components';
function Dashboard() {
const { breakpoint } = useBreakpoint();
const isMobile = breakpoint === 'xs' || breakpoint === 'sm';
const [navOpen, setNavOpen] = useState(false);
const nav = (
<IressCard>
<IressCard.Body>
<IressStack gap="2">
<IressText weight="strong">Navigation</IressText>
<IressText>Menu items here</IressText>
</IressStack>
</IressCard.Body>
</IressCard>
);
return isMobile ? (
<IressStack gap="4">
<IressButton
mode="secondary"
icon="menu"
onClick={() => setNavOpen(true)}
>
Menu
</IressButton>
<IressCard>
<IressCard.Body>
<IressText element="h2">Main Content</IressText>
</IressCard.Body>
</IressCard>
<IressSlideout
heading="Navigation"
show={navOpen}
onShowChange={setNavOpen}
>
{nav}
</IressSlideout>
</IressStack>
) : (
<IressRow gutter="lg">
<IressCol span={3}>{nav}</IressCol>
<IressCol span={9}>
<IressCard>
<IressCard.Body>
<IressText element="h2">Main Content</IressText>
</IressCard.Body>
</IressCard>
</IressCol>
</IressRow>
);
}
Best Practices
- Always wrap in IressProvider — Required at the root of your app for fonts and CSS variables.
IressProvideralready includesIressModalProvider,IressSlideoutProvider,IressToasterProvider, andIressIconProvider— do not add these separately. If usingIressShadow, no additional providers are needed as it includesIressProviderinternally. - Use IressField for all form inputs — Provides consistent labels, hints, and validation display
- Use IressStack/IressInline for layout — Prefer these over custom CSS flex/grid
- Use spacing tokens for gap — Values 0–10 map to multiples of 4px
- Use semantic button modes — One
primaryper section,secondaryfor most actions - Always include labels — All form inputs need accessible labels via
IressField - Use status for feedback —
IressAlertfor inline messages,IressModal status="danger"for confirmation dialogs,statusprop on buttons for danger/success - Prefer IDS components — Use
IressTextinstead of raw<p>,IressButtoninstead of<button> - Native elements inside
IressTextare OK — When rendering CMS content, markdown output, or other unstructured data sources, it is acceptable to nest native HTML elements (e.g.<p>,<strong>,<a>,<ul>) insideIressText. This letsIressTextprovide consistent typography while allowing flexible inner content structure. - Always make grid layouts responsive — When using
IressRow/IressCol, use responsivespanvalues (e.g.span={{ xs: 12, md: 6 }}) so columns stack on mobile instead of overflowing - Check the component docs — Read the specific component doc for detailed props and patterns (
node_modules/@iress-oss/ids-components/.ai/components/)
Common Mistakes
For the full list of common anti-patterns (disabled buttons, redundant textStyle, legacy slot attributes, raw HTML, hardcoded values), read the Common Mistakes guide at node_modules/@iress-oss/ids-components/.ai/guides/foundations-common-mistakes.md (requires @iress-oss/ids-components to be installed).