Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 22 additions & 5 deletions docs/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ The site resolves monorepo packages directly via aliases in `astro.config.mjs`:

## Content collections

Defined in `src/content/config.ts`. Three collections:
Defined in `src/content/config.ts`. Four collections:

### Components (`src/content/components/*.mdx`)

Expand Down Expand Up @@ -123,12 +123,29 @@ Content here...
</Preview>
```

**Topics** determine where guidance appears on the component page. Only these values are recognized by the rendering code in `src/lib/content-queries.ts`:
**Topics** determine where guidance appears on the component page. The full set is defined in `src/content/config.ts` and grouped for rendering in `src/lib/content-queries.ts`:

- **Usage tab:** `types`, `states`, `sizing`, `icons`, `positioning`, `content`, `other`
- **Accessibility tab:** `screen-readers`, `keyboard`, `focus`
- **Usage tab:** `types`, `states`, `sizing`, `icons`, `positioning`, `content`, `feedback`, `usage`, `interaction`, `forms`, `layout`, `performance`, `other`
- **Accessibility tab:** `accessibility`, `screen-readers`, `keyboard`, `focus`

The schema in `config.ts` accepts additional topic values (usage, interaction, forms, layout, performance, accessibility, feedback), but any guidance using those topics will be **silently filtered out** and won't render on the page. Stick to the values above.
### Foundations (`src/content/foundations/*.mdx`)

Design system knowledge documents: principles, anti-patterns, user type guidance. These are reference documents, not atomic items like guidance.

```yaml
---
id: principles
title: Design Principles
description: Core design and development principles for teams building with the GoA Design System
category: design # design | development | accessibility
tags: [government-service, accessibility, component-first]
status: published # published | draft | deprecated
---
```

The MDX body contains the actual content as structured markdown (headings, lists, etc.). Currently five files: `principles.mdx`, `anti-patterns.mdx`, `user-types.mdx`, `governance.mdx`, `responsive.mdx`.

No website pages render this collection yet. It exists for downstream consumers (generators, MCP) and can be wired to pages in the future.

### Examples (`src/content/examples/*/`)

Expand Down
18 changes: 18 additions & 0 deletions docs/src/content/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,8 +157,26 @@ const examples = defineCollection({
}),
});

/**
* Foundations Collection
* Design system knowledge documents (principles, anti-patterns, user types)
* These are reference documents, not atomic items like guidance
*/
const foundations = defineCollection({
type: "content",
schema: z.object({
id: z.string(),
title: z.string(),
description: z.string(),
category: z.enum(["design", "development", "accessibility"]),
tags: z.array(z.string()).optional(),
status: z.enum(["published", "draft", "deprecated"]).default("published"),
}),
});

export const collections = {
components,
guidance,
examples,
foundations,
};
106 changes: 106 additions & 0 deletions docs/src/content/foundations/anti-patterns.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
---
id: anti-patterns
title: Anti-Patterns
description: Common anti-patterns and pitfalls to avoid when using the GoA Design System
category: design
tags:
- anti-patterns
- common-mistakes
- code-quality
status: published
---

## Design Anti-Patterns

### Custom Components Over GoA Components

**Severity:** High

Building custom components when equivalent GoA components exist. This fragments the design system, increases maintenance burden, and introduces inconsistencies across government services.

**Detection:**

- Custom button, input, or layout components
- Reimplementation of existing patterns

**Solution:** Exhaust GoA library options before building custom. Check examples for similar patterns.

---

### Mismatched User Type Patterns

**Severity:** High

Using citizen patterns for worker tools or vice versa. Citizen and worker services have fundamentally different user needs and interaction models that must not be mixed.

**Detection:**

- Worker dashboards with one-question-per-page
- Citizen forms with high information density

**Solution:** Use appropriate patterns for each user type. See the User Types foundation.

---

### Inconsistent Layout Structure

**Severity:** Critical

Not following the right layout pattern for the service type. Citizen-facing services and worker tools have different layout requirements, and mixing patterns breaks visual hierarchy and user expectations.

**Detection:**

- Citizen-facing services (like public forms) missing AppHeader or AppFooter
- Worker tools mixing AppHeader/AppFooter with WorkSideMenu
- Inconsistent page structure within the same service

**Solution:** Use the layout pattern that matches the service type. Citizen services use AppHeader and AppFooter with OneColumnLayout. Worker tools use WorkSideMenu without standard header or footer.

---

### Accessibility as Afterthought

**Severity:** Critical

Adding accessibility features after design/development completion. Retrofitting accessibility is far more expensive than building it in from the start, and risks WCAG 2.2 AA non-compliance.

**Detection:**

- Form inputs without labels
- Missing ARIA attributes
- Color contrast issues

**Solution:** Use GoA components which provide accessibility by default. Test early.

---

## Technical Anti-Patterns

### Custom CSS Over Component Props

**Severity:** Medium

Trying to override GoA component appearance with custom CSS. Most attempts won't work anyway because the components use shadow DOM, which isolates styling. The ones that do work create fragile implementations that break on component updates and undermine visual consistency.

**Detection:**

- CSS selectors targeting GoA classes or elements
- !important declarations attempting to override component styles
- Wrapper elements with inline styles trying to influence components

**Solution:** Use component props first. If you genuinely need to customize a component beyond what props allow, GoA components expose component tokens (CSS custom properties) that can be overridden. This is the supported escape hatch and is far better than fighting the shadow DOM. If you find yourself reaching for tokens often, talk to the design system team — there may be a missing prop or a pattern worth adding.

---

### Overuse of GoabSpacer

**Severity:** Low

Using GoabSpacer instead of component margin properties. Excessive spacers add unnecessary DOM nodes and ignore built-in spacing controls on components.

**Detection:**

- Many GoabSpacer components
- Spacers between components that support margins

**Solution:** Use component margin props (mb, mt, ml, mr) when available.
78 changes: 78 additions & 0 deletions docs/src/content/foundations/governance.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
---
id: governance
title: Working with the Design System
description: How teams work with the design system. The happy path for using existing components, requesting changes, and contributing back.
category: design
tags:
- governance
- process
- contribution
status: published
---

## The Happy Path

The design system is a shared resource. Teams work with it through a simple, repeatable process. The goal is to use what exists when it works, talk to the team when it doesn't, and decide together whether something becomes shared or stays a one-off.

### 1. Use what exists

Start with the design system. Existing components and patterns cover most service needs. Search the components, look at the examples, and see if you can build what you need with what's already there.

### 2. Identify the gap

If you find a real user need that existing components don't handle, that's the signal to talk to the design system team. Real user need means it came from research, testing, or actual service requirements. Not preference, not aesthetic, not "we've always done it this way."

### 3. Talk to the design system team

Bring the gap to the team. Don't build around it in isolation. The team can help you understand whether what you need already exists in a form you missed, whether it should be added to the system, or whether your situation is unique enough to be a one-off.

### 4. Apply the problem-solving hierarchy

When something doesn't fit, work through these in order before reaching for new components:

1. **Change the content.** Clearer labels, better instructions, simpler language often solve the problem.
2. **Change the layout.** Rearrange elements, adjust spacing, improve grouping.
3. **Design new components.** Only when content and layout changes don't work.

Most problems get solved in the first two steps.

### 5. Test with users

Validate any new solution with actual users. The design system is evidence-based. Decisions are driven by usability testing and real user needs, not preferences.

### 6. Share what you learned

Solutions either get added to the system for everyone, or stay as one-offs for your team. Either way, the design system team needs to know what was tried and what worked so other teams can benefit from the learning.

## Contribution Criteria

For something to enter the shared design system, it needs to be:

- **Useful** — Evidence that the component would be valuable to many teams or services, not just one
- **Unique** — Does not replicate something that already exists in the design system
- **Better** — Creates a better experience, informed by research
- **Universal** — Meets or exceeds WCAG 2.2 AA accessibility standards

## Roles

**Design system team:** Guides component selection, reviews compliance, provides expertise, decides what enters the shared system.

**Product teams:** Define user needs, implement with GoA components, share learnings back.

Product teams can do what they need to ship their service. The design system team decides what becomes shared across teams. These are two different decisions.

## Where to find the team

- **Design System Support channel** on Slack
- **Drop-in Hours** sessions
- **Report a Bug** system for issues
- **Governance board** in FigJam: visual map of the full process and decision points

## Risk Indicators

If you notice any of these, it's a signal to pause and talk to the design system team:

- Building custom components that already exist
- Making changes without user validation
- Working in isolation without design system consultation
- Creating solutions that don't meet accessibility standards
65 changes: 65 additions & 0 deletions docs/src/content/foundations/principles.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
---
id: principles
title: Design Principles
description: Core design and development principles for teams building with the GoA Design System
category: design
tags:
- government-service
- accessibility
- component-first
- spacing
status: published
---

## Core Principles

### Government Service First

All design decisions must prioritize citizen and worker needs over aesthetic preferences.

**Application:** Choose components and patterns based on user research and government service requirements.

### Accessibility by Default

WCAG 2.2 AA compliance is non-negotiable, not an add-on.

**Application:** Use GoA components which provide built-in accessibility features.

### Consistency Over Creativity

Consistent user experience across government services trumps unique design.

**Application:** Use established GoA patterns rather than inventing new ones.

### Component-First Thinking

Exhaust GoA component library options before building custom components.

**Application:** Search the component library, check examples, combine existing components creatively.

## Development Principles

### Component-First Process

Always start with GoA components until those options are fully exhausted before doing any custom components.

1. Search for GoA components that solve your need
2. Search with multiple terms (e.g., 'button', 'action', 'submit')
3. Check examples for similar patterns
4. If no component found: Ask the team before building custom

### Spacing Strategy

Use component margin props (mb, mr) as the primary spacing approach.

- Component margin props (mb, mr, mt, ml) - preferred
- GoabBlock for flex layouts
- Custom flexbox/grid when needed
- GoabSpacer for explicit gaps (less responsive)

### Validation Checklist

- Verify component properties against documented valid values
- Check design specifications for exact sizing
- Ensure no custom styling - only use component props
- Validate spacing tokens match design system
44 changes: 44 additions & 0 deletions docs/src/content/foundations/responsive.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
---
id: responsive
title: Responsive Design
description: Components handle responsive behavior automatically. Trust the defaults, and reach for explicit responsive controls only when you need them.
category: design
tags:
- responsive
- breakpoints
- mobile
- layout
status: published
---

## Trust the defaults

Most GoA components handle responsive behavior internally. A button is full-width on mobile and inline on larger screens. A form item stacks its label on mobile and aligns it inline on desktop. A header collapses to a hamburger menu on small screens. You don't need to write media queries to make these things happen.

The general rule: build with components, and the responsive behavior comes with them. Reach for explicit responsive control only when you need something the components don't handle on their own.

## Container queries

Many components use container queries instead of viewport media queries, which means they respond to the size of their container, not the size of the window. A component placed in a narrow sidebar adapts to that sidebar even on a wide screen. This is mostly invisible — it just works — but it's worth knowing because it changes how you think about responsive layouts. Components don't always look the same at the same viewport width. They look right for the space they're in.

## Breakpoints

When you do need to think about screen size explicitly, the design system uses three breakpoints:

- **Mobile** — under 624px. Phones and small devices.
- **Tablet** — 624px to 1023px. Tablets and medium devices.
- **Desktop** — 1024px and above. Desktop and larger screens.

These align with how the components themselves adapt, so if you're building custom layouts around GoA components they'll work together at the same breakpoints.

## Mobile considerations

Mobile is where responsive matters most. A few patterns to keep in mind:

- Buttons go full-width by default on mobile, can be overridden
- Form layouts stack labels above inputs
- Navigation collapses
- Block direction switches to column regardless of the direction prop
- Single-column content beats multi-column

These happen automatically with the components, but if you're laying out a custom screen, follow the same principles.
Loading
Loading