Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
69afb23
Add Calendar component with locale, controlled month, and renderDay s…
jaymantri Mar 1, 2026
07f978c
Fix Calendar edge cases, accessibility, and add comprehensive tests
jaymantri Mar 2, 2026
664c60a
Overhaul chart library: add new charts, keyboard a11y, and polish
jaymantri Mar 3, 2026
7e83212
Fix demo page ordering, section gaps, and Sankey layout overflow
jaymantri Mar 3, 2026
d0a34c7
Rename Calendar component to DatePicker
jaymantri Mar 3, 2026
e0f2b09
Prepare repo for public visibility
jaymantri Mar 3, 2026
2cbfc9a
Generalize product references in rules and commands
jaymantri Mar 3, 2026
e506433
Replace internal Vercel URLs with generic mock data
jaymantri Mar 3, 2026
b42fc11
Update README for public repo clarity
jaymantri Mar 3, 2026
a8523a0
Remove unused motion dependency
jaymantri Mar 3, 2026
14fb6b2
Add comprehensive Drawer stories for all variants and features
jaymantri Mar 4, 2026
54132f9
Harden chart library: analytics, prop renames, a11y, and structural c…
jaymantri Mar 4, 2026
6f49fa6
Add Storybook controls and remove redundant variant stories
jaymantri Mar 5, 2026
ae93c75
Harden Drawer: outline borders, handle a11y, action sheet, and test c…
jaymantri Mar 5, 2026
86dc6cf
Update design tokens: alpha surfaces, border opacity, and dark mode r…
jaymantri Mar 5, 2026
dada391
Use semantic surface-alpha-secondary token for button secondary backg…
jaymantri Mar 5, 2026
6f39a3e
Add Skeleton component with group-synced subtractive shimmer
jaymantri Mar 5, 2026
d372219
Consolidate loading skeletons to Skeleton component
jaymantri Mar 5, 2026
3417f83
Align chart ARIA with WAI-ARIA Graphics Module and fix CI failures
jaymantri Mar 5, 2026
603e341
Use role="img" for non-interactive Line charts (fixes Sparkline test)
jaymantri Mar 5, 2026
29de567
Fix Sparkline test fixtures to pass interactive={false}
jaymantri Mar 5, 2026
f19db2b
Update alpha surface tokens: shift scale from 2/4/6 to 4/6/10 percent
jaymantri Mar 5, 2026
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
2 changes: 1 addition & 1 deletion .cursor/commands/build-component.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@
- `npm run build` — catch export/import errors
- `npm test` — full test suite

14. **Publish (if ready for Grid)**:
14. **Publish (if ready for consumers)**:
> "Component is exported and tested. Ready to publish?
> - Yes → Follow `publishing.mdc` to release a new version
> - Not yet → Skip, publish later with other changes"
Expand Down
3 changes: 0 additions & 3 deletions .cursor/environment.json

This file was deleted.

14 changes: 7 additions & 7 deletions .cursor/rules/boundary.mdc
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ alwaysApply: true

# Origin Boundary

Origin is the design system. Products like Grid consume it.
Origin is the design system. Products consume it as a package dependency.

## This Repo

Expand All @@ -15,11 +15,11 @@ Origin is the design system. Products like Grid consume it.
- Design tokens and typography
- Before adding logic to a component, pause and ask: should this logic live in the primitive or in the product? Check with the user before proceeding.

## Grid Reference
## Product Reference

Grid (`/Users/ajaymantri/dev/grid`) is a product built on Origin.
If a consuming product repo exists in the workspace, use it as read-only reference:

- **Read-only** — never modify Grid files from this workspace
- **Never modify** product files from this workspace
- Use as reference for how Origin components are consumed in practice
- Learn from real usage patterns when designing component APIs

Expand All @@ -28,8 +28,8 @@ Grid (`/Users/ajaymantri/dev/grid`) is a product built on Origin.
| If you're adding... | It belongs in... |
|---------------------|------------------|
| Reusable UI pattern | Origin |
| Product-specific layout | Grid (or other product) |
| Product-specific layout | Consuming product |
| Generic interaction (button, input) | Origin |
| Business logic | Grid (or other product) |
| Business logic | Consuming product |
| Design tokens | Origin |
| App-specific tokens | Grid (or other product) |
| App-specific tokens | Consuming product |
41 changes: 38 additions & 3 deletions .cursor/rules/charts.mdc
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,24 @@ globs:
| `Chart.Line` | Line chart, area chart (via `fill` prop), sparkline-like |
| `Chart.Sparkline` | Compact inline chart — no axes, no interaction |
| `Chart.StackedArea` | Stacked cumulative area bands |
| `Chart.Bar` | Grouped or stacked bar chart |
| `Chart.Bar` | Grouped, stacked, or horizontal bar chart |
| `Chart.Pie` | Donut chart with legend sidebar |
| `Chart.Composed` | Mixed bar + line with dual Y-axes |
| `Chart.Gauge` | Arc gauge with thresholds and marker |
| `Chart.BarList` | Horizontal bars with labels — supports rank numbers, change indicators, secondary values |
| `Chart.Uptime` | Binary status timeline (up/down) |
| `Chart.Live` | Canvas streaming chart with `requestAnimationFrame` |
| `Chart.Scatter` | XY scatter plot — multi-series, nearest-point tooltip |
| `Chart.Split` | Segmented distribution bar — parts of a whole |
| `Chart.Sankey` | Flow diagram — multi-path node/link with contextual hover filtering |
| `Chart.Funnel` | Conversion funnel with tapered stages and drop-off rates |
| `Chart.Waterfall` | Waterfall chart — running total with increases, decreases, totals |

## Color Strategy

### Single series

Use `color` prop or `dataKey` — the component defaults to `var(--border-primary)`.
Use `color` prop or `dataKey` — the component defaults to `var(--stroke-primary)`.

```tsx
<Chart.Line data={data} dataKey="value" color="var(--color-blue-600)" />
Expand Down Expand Up @@ -82,7 +91,7 @@ Pattern: `var(--color-{hue}-{stop})`

When no `color` is set on a series, the component auto-assigns from `SERIES_COLORS`:

1. `var(--border-primary)` (near-black)
1. `var(--stroke-primary)` (near-black)
2. `var(--text-secondary)` (gray)
3. `var(--surface-blue-strong)`
4. `var(--surface-purple-strong)`
Expand All @@ -99,3 +108,29 @@ This palette is designed for distinct-hue multi-series. For stacked/grouped char
- **Do not** hardcode hex colors — use tokens
- **Do not** rely on the fallback palette for stacked charts — the distinct hues look incohesive when stacked
- **Do not** use semantic surface tokens (`--surface-blue-strong`) when you need shade control — use the primitive scale instead

## Sankey vs Funnel

Use **Funnel** when the flow is strictly sequential — every user passes through every stage in order and you care about drop-off rates between stages.

Use **Sankey** when the flow branches — users take different paths to different outcomes, and you need to show how volume splits and merges across multiple routes.

| | Funnel | Sankey |
|---|---|---|
| Data shape | Linear sequence (A → B → C) | Directed graph (A → B, A → C, B → D) |
| Key metric | Conversion rate between stages | Volume per path |
| Best for | Single-path conversion funnels | Multi-path routing, budget allocation, attribution |

## Interaction Contract

Each chart type exposes a click handler matching its data model:

| Component | Handler |
|---|---|
| `Chart.Line`, `Chart.Bar`, `Chart.Composed`, `Chart.StackedArea`, `Chart.Pie` | `onClickDatum(index: number, datum: Record<string, unknown>) => void` |
| `Chart.Split` | `onClickDatum(segment: SplitSegment, index: number) => void` |
| `Chart.Scatter` | `onClickDatum(seriesKey: string, point: ScatterPoint, index: number) => void` |
| `Chart.BarList` | `onClickDatum(item: BarListItem, index: number) => void` |
| `Chart.Funnel` | `onClickDatum(index: number, stage: FunnelStage) => void` |
| `Chart.Waterfall` | `onClickDatum(index: number, segment: WaterfallSegment) => void` |
| `Chart.Sankey` | `onClickNode(node: LayoutNode) => void` / `onClickLink(link: LayoutLink) => void` |
126 changes: 0 additions & 126 deletions .cursor/rules/motion.mdc

This file was deleted.

6 changes: 3 additions & 3 deletions .cursor/rules/publishing.mdc
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Origin publishes to GitHub Packages on release.

## When to Publish

- After component additions/changes ready for Grid consumption
- After component additions/changes ready for consumption
- After token updates
- After bug fixes affecting consumers

Expand All @@ -20,7 +20,7 @@ gh release create vX.Y.Z --title "vX.Y.Z" --generate-notes

- Verify build passes: `npm run build`
- Verify tests pass: `npm run test:unit`
- Update Grid's dependency version after publishing
- Update the consuming product's dependency version after publishing

## Version Guidelines

Expand All @@ -30,7 +30,7 @@ gh release create vX.Y.Z --title "vX.Y.Z" --generate-notes

## After Publishing

In Grid, update to the new version:
In the consuming product, update to the new version:

```bash
npm install @lightsparkdev/origin@latest
Expand Down
8 changes: 8 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Required for npm install (Central Icons license)
CENTRAL_LICENSE_KEY=

# Required for npm run figma:styles and npm run figma:node
FIGMA_TOKEN=

# Required for npm run figma:styles (Figma design file key)
FIGMA_FILE_KEY=
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,10 @@ origin.code-workspace

# Cursor workspace handoff
handoff/

# Cursor auto-generated
.cursor/environment.json

# Ephemeral plan files
.cursor/plans/
docs/plans/
2 changes: 1 addition & 1 deletion CONTEXT.md
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ The `tools/` directory is excluded from the main tsconfig since it has Figma-spe

## Related Files

- **Figma Design System**: https://www.figma.com/design/3JvbUyTqbbPL8cCpwSX0j4/Origin-design-system
- **Figma Design System**: Set `FIGMA_FILE_KEY` in `.env.local` — see `.env.example`
- **Base UI Docs**: https://base-ui.com/react/components

---
Expand Down
13 changes: 10 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ src/
└── app/ # Next.js app

tools/
└── base-ui-lint/ # Figma structure validation plugin
├── base-ui-lint/ # Figma structure validation plugin
└── figma-styles/ # Internal Figma style sync (requires credentials)

tokens/
└── figma/ # Raw Figma token exports
Expand Down Expand Up @@ -61,6 +62,10 @@ import { CentralIcon } from '@/components/Icon';

213 vendored icons from Central Icons. Edit `scripts/extract-icons.mjs` to add icons, then run `npm run icons:extract`.

## Tokens

Color and spacing tokens are built from exported Figma variables (`npm run tokens:build`). Typography mixins (`_text-styles.scss`) and shadow variables (`_effects.scss`) are generated from an internal Figma file and committed to the repo — external contributors don't need to regenerate them. Don't edit these generated files by hand.

## Scripts

| Command | Description |
Expand All @@ -75,6 +80,8 @@ import { CentralIcon } from '@/components/Icon';
| `npm run test:all` | Run both test suites |
| `npm run lint` | Run ESLint |

Internal maintainers with Figma credentials also have `figma:styles` and `figma:node` for syncing styles from the design file.

## Using as a Package

### Installation
Expand Down Expand Up @@ -149,7 +156,7 @@ For full setup details, see [Using Origin in Your App](docs/using-origin-in-your

## Typography

Suisse Intl requires font metric overrides to prevent an oversized text caret in inputs:
Suisse Intl uses font metric overrides for precise line-height control:

```scss
@font-face {
Expand All @@ -160,7 +167,7 @@ Suisse Intl requires font metric overrides to prevent an oversized text caret in
}
```

These values are applied to all weights (Regular, Book, Medium) in `_fonts.scss`. Consuming apps **must** import Origin's fonts to get correct input rendering.
These values are applied to all weights (Regular, Book, Medium) in `_fonts.scss`. Consuming apps should import Origin's fonts for correct input rendering. Without the font, the system falls back to `system-ui`.

## Documentation

Expand Down
1 change: 0 additions & 1 deletion docs/component-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ Fallback for CSS: `npm run figma:node "<figma-url>"`
| Base UI exists | `components.mdc` |
| Composed from Base UI | `components.mdc` |
| No Base UI | `custom-components.mdc` |
| Animations | `motion.mdc` |

## Code Style

Expand Down
Loading