This document provides comprehensive instructions for AI assistants working on the GoA Design System documentation website (ui-components-docs). Understanding this architecture is critical for making safe, effective changes.
- Project Overview
- GoabText Spacing System
- Website Architecture
- Version & Framework System
- Component Property Documentation
- Spacing Patterns by Page Type
- Development Workflow
- Areas Requiring Special Care
- Common Tasks & Guidelines
- Quality Assurance
- Framework: React 18.2.0 + TypeScript + Vite
- Design System:
@abgov/react-componentsv6.6.1,@abgov/web-componentsv1.36.1 - Routing: React Router v6.13.0
- Styling: CSS Modules + Design System components
- Dynamic Content: Much content is GitHub-sourced and version-dependent
- Multi-Version Support: 4 versions (LTS/Latest × React/Angular)
- Component Reuse: Examples shared between individual pages and component documentation
- Semantic HTML: Always use proper heading hierarchy with
tagprop - Default-First Design: GoabText has intelligent defaults, override only when needed
GoabText now has built-in default margins that provide good starting values for most scenarios. The defaults ensure text never gets cramped and creates proper visual hierarchy automatically.
Default Top Margins by Size:
heading-xl:2XLheading-l:2XLheading-m:2XLheading-s:XLheading-xs:XLbody-l:2XLbody-m:Lbody-s:Lbody-xs:S
Default Bottom Margins by Size:
heading-xl:Lheading-l:Lheading-m:Mheading-s:Sheading-xs:XSbody-l:Lbody-m:Lbody-s:Lbody-xs:L
- Connected Content: Use
mt="none"when content should flow directly from previous element - Container Boundaries: Use
mt="none"ormb="none"at container edges for alignment - Custom Relationships: Override with specific values when design requires different spacing
- Legacy Cleanup: Remove explicit margins that now duplicate the new defaults
Always use proper semantic tags with the tag prop:
// ✅ CORRECT: Semantic h1 with visual flexibility
<GoabText tag="h1" size="heading-xl">Page Title</GoabText>
// ❌ WRONG: Missing semantic meaning
<GoabText size="heading-xl">Page Title</GoabText>
// ❌ WRONG: Raw HTML instead of GoabText
<h1>Page Title</h1>src/routes/
├── home.tsx # Landing page
├── get-started/ # Onboarding content
│ ├── GetStartedOverview.tsx
│ ├── developers/ # Developer guides
│ ├── designers/ # Designer resources
│ └── qa-testing/ # QA testing guides
├── foundations/ # Design principles (safe for systematic changes)
│ ├── Accessibility.tsx
│ ├── Color.tsx
│ ├── Typography.tsx
│ └── [other foundation pages]
├── components/ # Component documentation (REQUIRES MANUAL REVIEW)
├── examples/ # Usage patterns (REQUIRES MANUAL REVIEW)
└── design-tokens/ # Design token documentation (safe for systematic changes)
├── color/
├── spacing/
└── [other token pages]
- ComponentContent: Wrapper for consistent page structure with table of contents
- CardLite: Reusable navigation cards used throughout the site
- AccessibilityEmpty: Shared accessibility guidance component
- Sandbox: Interactive component playground (components section only)
- ExamplePageTemplate: Dynamic template for individual example pages
- Static Content: Foundations, Get Started, Design Tokens (manually maintained)
- GitHub-Sourced Metadata: Component and example descriptions, status, links
- Dynamic Templates: Examples and component pages use template systems
- Shared Examples: Individual example components reused across contexts
The website supports 4 distinct versions of code examples:
- LTS/React (
version === "old",tags="react") - Latest/React (
version === "new",tags="react") - LTS/Angular (
version === "old",tags="angular") - Latest/Angular (
version === "new",tags="angular")
import { LanguageVersionContext } from "@contexts/LanguageVersionContext.tsx";
const {version, language} = useContext(LanguageVersionContext);
// Conditional rendering based on version
{version === "new" && <CodeSnippet ... />}
{version === "old" && <CodeSnippet ... />}
// Framework-specific content
tags="react"
tags="angular"
tags={["angular", "reactive"]} // Angular reactive forms
tags={["angular", "template-driven"]} // Angular template-driven forms- LTS:
GoAprefix,goa-HTML tags,(_click)events - Latest:
Goabprefix,goab-HTML tags,(onClick)events
Examples must support all 4 versions:
export const ExampleComponent = () => {
const {version} = useContext(LanguageVersionContext);
return (
<Sandbox flags={["reactive"]}>
{/* Visual demo that works across all versions */}
<GoabButton onClick={noop}>Demo Button</GoabButton>
{/* Version-specific React code */}
{version === "old" && <CodeSnippet tags="react" code={`<GoAButton ...>`} />}
{version === "new" && <CodeSnippet tags="react" code={`<GoabButton ...>`} />}
{/* Version-specific Angular code */}
{version === "old" && <CodeSnippet tags="angular" code={`<goa-button ...>`} />}
{version === "new" && <CodeSnippet tags="angular" code={`<goab-button ...>`} />}
</Sandbox>
);
};- Type Definitions →
ui-components/libs/common/src/lib/common.ts - React Interface →
ui-components/libs/react-components/src/lib/[component]/[component].tsx - Documentation Props →
ui-components-docs/src/routes/components/[Component].tsx
export type ComponentProperty = {
name: string; // Property name
type?: string | string[]; // TypeScript type + inline union values
lang?: "react" | "angular"; // Framework-specific props
required?: boolean; // Required property flag
description?: string; // Human-readable description
defaultValue?: string; // Default value if any
badge?: { content: string; type: GoabBadgeType }; // Special badges
};// Component-specific properties
const componentProperties: ComponentProperty[] = [
{
name: "type",
type: "GoabButtonType (primary | submit | secondary | tertiary | start)",
description: "Sets the type of button.",
defaultValue: "primary",
},
// Framework-specific variations
{
name: "leadingIcon",
type: "GoabIconType",
lang: "react",
description: "Shows an icon to the left of the text.",
},
{
name: "leadingicon", // lowercase for Angular
type: "GoabIconType",
lang: "angular",
description: "Shows an icon to the left of the text.",
},
// Shared properties (reuse these)
TestIdProperty, // From common-properties.ts
MarginProperty, // From common-properties.ts
];
// Legacy version properties
const oldComponentProperties: ComponentProperty[] = [
// Properties for LTS version
];The ComponentProperties component automatically:
- Filters properties by framework (React vs Angular)
- Filters properties by version (LTS vs Latest)
- Displays context-appropriate properties
When updating component documentation:
- Check type definitions in
common.tsfirst - Update React interface if needed
- Update documentation arrays to match
- Use shared properties from
common-properties.tswhen possible - Maintain version differences between old/new property arrays
<GoabText tag="h1" size="heading-xl">Page Title</GoabText>
<GoabText size="body-l" mt="none">Introduction paragraph explaining the page content.</GoabText>- Title: Uses default
2XLtop +Lbottom margins - Introduction: Uses
mt="none"to connect to title, default bottom margin
Get Started Developer/Designer/QA pages:
<GoabText size="heading-m">Developers</GoabText>
<GoabText tag="h1" size="heading-xl" mt="none">Specific Page Title</GoabText>
<GoabText size="body-l" mt="none">Introduction paragraph</GoabText>Foundation Pages with Content Guidelines/Style Guide:
<GoabText size="heading-m">Content guidelines</GoabText> {/* or "Style guide" */}
<GoabText tag="h1" size="heading-xl" mt="none">Page Title</GoabText>
<GoabText size="body-l" mt="none">Introduction paragraph</GoabText>Foundation Category Assignment:
- Content Guidelines: ErrorMessages, HelperText, DateFormat, Capitalization
- Style Guide: Color, Iconography, Photography, Logo, Typography, Layout
<GoabText tag="h1" size="heading-xl">Token Name</GoabText>- Critical: Never use
<h1>tags - always useGoabTextwithtag="h1" - Let defaults handle all spacing
When GoabText is inside GoabContainer:
- First element: Consider
mt="none"for edge alignment - Last element: Consider
mb="none"for edge alignment - Important: Only override when visual alignment requires it
- Always read files first before editing to understand current structure
- Check for double spacing caused by explicit margins + new defaults
- Test with defaults first - only override when content relationships require it
- Understand page context - different sections have different patterns
npm run dev # Start development server
npm run build # Build for production
npm run lint # Run ESLint
npm run prettier # Format code
npm run make:route # Create new route (script available)- Always read existing files before making changes
- Check imports and dependencies to understand component usage
- Verify spacing patterns match established hierarchy
- Look for
<h1>tags that should be converted toGoabTextwithtag="h1"
- Foundations section (
src/routes/foundations/) - Static content pages - Get Started section (
src/routes/get-started/) - Onboarding content - Design Tokens section (
src/routes/design-tokens/) - Token documentation - Home page (
src/routes/home.tsx) - Landing page content
- Examples section (
src/routes/examples/,src/examples/)- Dynamic template system
- GitHub integration
- 4-version code snippet requirements
- Shared components with specific layout needs
- Components section (
src/routes/components/)- Interactive sandboxes
- Property documentation tables
- Version-specific functionality
- Technical content with different hierarchy needs
- ExamplePageTemplate dynamically imports examples based on URL slug
- Individual examples reused across multiple component documentation pages
- Sandbox components have specific spacing needs for interactive functionality
- Version switching affects code snippet display throughout examples
- GitHub metadata drives descriptions, tags, and status - don't edit manually
// ❌ BEFORE: Raw HTML
<h1>Page Title</h1>
// ✅ AFTER: Semantic GoabText
<GoabText tag="h1" size="heading-xl">Page Title</GoabText>// ❌ BEFORE: Double spacing (explicit + defaults)
<GoabText size="heading-xl" mt="xl" mb="m">Title</GoabText>
// ✅ AFTER: Trust defaults, override relationships
<GoabText tag="h1" size="heading-xl">Title</GoabText>
<GoabText size="body-l" mt="none">Connected introduction</GoabText>- Define types in
ui-components/libs/common/src/lib/common.ts - Add to React interface in component file
- Update documentation in component page:
const componentProperties: ComponentProperty[] = [
{
name: "newProp",
type: "NewPropType (value1 | value2)",
description: "Description of the new property.",
defaultValue: "value1",
},
// ... existing props
];Examples must support 4 versions and be reusable:
import { LanguageVersionContext } from "@contexts/LanguageVersionContext.tsx";
export const NewExample = () => {
const {version} = useContext(LanguageVersionContext);
return (
<Sandbox flags={["reactive"]}>
{/* Interactive demo */}
<GoabComponent />
{/* 4 version-specific code snippets */}
{version === "old" && <CodeSnippet tags="react" ... />}
{version === "new" && <CodeSnippet tags="react" ... />}
{version === "old" && <CodeSnippet tags="angular" ... />}
{version === "new" && <CodeSnippet tags="angular" ... />}
</Sandbox>
);
};Most foundation pages need subtitle categorization:
// Add appropriate subtitle
<GoabText size="heading-m">Content guidelines</GoabText> // or "Style guide"
<GoabText tag="h1" size="heading-xl" mt="none">Page Title</GoabText>
<GoabText size="body-l" mt="none">Introduction paragraph</GoabText>- CardLite: Used for navigation cards throughout site
- AccessibilityEmpty: Common accessibility guidance (has specific spacing requirements)
- ComponentContent: Page wrapper with TOC support
- Changes to shared components affect multiple pages
- Page titles use
tag="h1"withsize="heading-xl" - Introduction text uses
size="body-l"withmt="none"when following titles - Section headings follow proper hierarchy (h2, h3, etc.)
- Spacing creates clear content flow without excessive gaps
- Container boundaries align properly
- No raw
<h1>tags (useGoabTextwithtag="h1") - Proper subtitle patterns on Foundation and Get Started pages
- Container spacing rules applied correctly when needed
- Component imports are correct
- No double spacing from explicit margins + defaults
- Connected content uses
mt="none"appropriately - Section breaks have adequate separation (defaults usually sufficient)
- Related content appears visually connected
- Unrelated content has clear separation
- 4 code versions supported (LTS/Latest × React/Angular)
- Proper version context usage (
version === "new"vsversion === "old") - Correct component prefixes (
GoAvsGoab) - Appropriate framework tags on code snippets
- Interactive demos work across all versions
- Type definitions exist in
common.ts - React interface matches documentation
- Property arrays include all interface properties
- Shared properties reused from
common-properties.ts - Version differences properly documented
- Framework-specific properties handled correctly
- Don't add explicit margins unless overriding defaults for content relationships
- Don't ignore semantic HTML - always use
tagprop for proper heading hierarchy - Don't edit GitHub-sourced metadata manually
- Don't apply systematic changes to examples/components sections without understanding their complexity
- Don't batch update spacing without testing visual results
- Don't assume examples are simple - they support 4 versions and are reused across contexts
- Read and understand existing file structure before making changes
- Test with default spacing first before adding overrides
- Override only for content relationships that require tighter spacing
- Verify semantic heading hierarchy is maintained
- Check spacing on both desktop and mobile if possible
- Ensure changes align with design system principles
- Examples section changes beyond simple content updates
- Component property changes that affect TypeScript interfaces
- New component creation or major architectural changes
- Version system modifications
- Uncertain about spacing patterns for specific page types
Look for these patterns that may now create excessive spacing:
// LEGACY: May create double spacing
<GoabText size="heading-xl" mt="xl" mb="m">Title</GoabText>
// CURRENT: Trust defaults, override relationships
<GoabText tag="h1" size="heading-xl">Title</GoabText>
<GoabText size="body-l" mt="none">Connected content</GoabText>- Page titles and introductions - Most likely to have excessive spacing
- Foundation pages - Need subtitle categorization and spacing cleanup
- Design token pages - Convert
<h1>tags toGoabText - Container boundaries - Check for proper edge alignment
- Content hierarchies - Verify proper flow relationships
- Current instructions:
/CLAUDE.md- Historical context and spacing evolution - GoabText implementation:
ui-components/libs/web-components/src/components/text/Text.svelte - Common properties:
src/components/component-properties/common-properties.ts - Version constants:
src/components/version-language-switcher/version-language-constants.ts
- Start development server:
npm run dev - Navigate to affected pages and verify spacing
- Test version switching if working with examples/components
- Check both desktop and mobile views when possible
- Compare with similar pages for consistency
- Verify semantic HTML in browser dev tools
- Review existing similar pages for established patterns
- Check design system component documentation for proper usage
- Test changes in development environment before assuming they're correct
- Refer to this document for spacing standards and architectural understanding
Remember: This website is a sophisticated, multi-version, GitHub-integrated documentation platform. The GoabText defaults provide excellent starting points - your job is to override intelligently for content relationships and maintain the semantic HTML structure that makes the site accessible and SEO-friendly. Always prioritize user experience and design system principles in your updates.