Skip to content

Component Library

Objectuve uses Storybook to document and develop UI components in isolation. The full design system showcase lives at design.objectuve.com.

Browsing Components

Running locally

bash
cd ionic_frontend
npm run storybook
# → http://localhost:6006

Story organization

Stories are co-located next to their components as ComponentName.stories.ts. The project currently includes 352 stories covering core UI elements, admin dashboard views, and design system tokens.

Example story structure

typescript
import type { Meta, StoryObj } from '@storybook/vue3'
import MyComponent from './MyComponent.vue'

const meta: Meta<typeof MyComponent> = {
  component: MyComponent,
  tags: ['autodocs'],
  argTypes: {
    // Define prop controls
  },
}

export default meta
type Story = StoryObj<typeof MyComponent>

export const Default: Story = {
  args: {
    // Default prop values
  },
}

Conventions

  • Tags: Always include tags: ['autodocs'] for automatic documentation generation
  • ArgTypes: Define argTypes for all public props to enable interactive controls
  • Decorators: Use Ionic and Apollo decorators from .storybook/decorators/ when components depend on those providers
  • Naming: Story files must match the component name: GoalCard.vueGoalCard.stories.ts

When to add a story

Add or update a story when:

  • Creating a new component
  • Adding new props or variants to an existing component
  • Fixing a visual bug (add a story that reproduces the bug first)

Design philosophy

Objectuve is an anti-social app — designed for ~10 min/day sessions. Components should prioritize:

  • Quick interactions — one-tap check-ins, immediate feedback (streak tick, XP pop, badge unlock)
  • Clear progress signals — visible momentum so users feel accomplishment, not obligation
  • No engagement hooks — no infinite scroll, no autoplay, no FOMO mechanics

See the Brand Guide for full tone, messaging, and visual identity details.

Design tokens

  • Primary gradient: #177bbb → #05cbfc
  • Accent orange: #f28529
  • Gold (achievements): #fcc419
  • Fonts: Outfit (headlines), Inter (body)

PageHeader ink contract (OBJ-2966)

design_system/src/components/layout/PageHeader.vue — the per-route header used across every design_system page — separates its decorative accent from its text ink. --page-accent (looked up per route from PAGE_ACCENTS[path], design_system/src/lib/pageAccents.ts) still drives the wash, icon-tile fill, inset ring, and header rule, but the eyebrow text and icon glyph read from a dedicated heroInkLight/heroInkDark pair instead of the decorative hue directly — each cleared against the worse of --background and the .page-hero wash (4.5:1 eyebrow text, 3:1 icon glyph). A new route added to PAGE_ACCENTS must register both ink values or its header silently falls back to --primary-accessible. Full rule and per-route value table: DESIGN.md § Palette intent § Accessibility hard rules — Page-Accent Ink Contract (OBJ-2966) and docs/ui-specs/obj-2966-page-accent-ink.md.

Last updated: 2026-09-11 — OBJ-3648: corrected the stale Storybook story count (189 → 352), matching the re-verified count from OBJ-3647

Loading…